Kategori: Code Snipet

  • Kelebihan Frontend situs web Next JS

    Kelebihan Frontend situs web Next JS

    Gambar ilustrasi next js

    NextJS: Arsitektur Modern & Performa Tinggi

    Halaman ini dibangun menggunakan framework Next JS dan dideploy melalui infrastruktur Cloudflare Pages & Workers dengan WordPress sebagai Backend.


    Penggunaan Next.js memungkinkan situs ini menyajikan konten secara instan melalui teknik Static Site Generation (SSG). Dengan memproses halaman sebelum pengunjung datang, waktu muat menjadi sangat singkat, meningkatkan skor SEO secara signifikan, dan memberikan pengalaman navigasi yang mulus tanpa jeda pemuatan halaman tradisional.

    Cloudflare Global Network

    Didukung oleh Cloudflare Global Network, aset web didistribusikan ke ratusan pusat data di seluruh dunia. Melalui teknologi Edge Computing dari Cloudflare Workers, logika aplikasi dijalankan di lokasi terdekat dengan Anda, meminimalkan latensi dan memastikan keamanan tingkat tinggi melalui proteksi WAF yang berlapis.

    Solusi Web Headless Modern

    Performa Ekstrem

    Optimalisasi Next.js memastikan skor Core Web Vitals Anda selalu berada di zona hijau.

    Keamanan Berlapis

    Infrastruktur Cloudflare melindungi situs Anda dari serangan DDoS dan ancaman bot.

    Fleksibilitas API

    Mengintegrasikan WPGraphQL untuk manajemen konten yang dinamis dan terstruktur.

  • Code Snipet Multi Bahasa Gratis Tanpa plugin wpml polylang

    Code Snipet Multi Bahasa Gratis Tanpa plugin wpml polylang

    Code snipet multi bahasa pujashanti

    Code Snipet Multi Bahasa

    Sebelum mulai langkah-langkah injeksi Code Snipet Multi Bahasa Gratis Tanpa plugin wpml polylang sangat direkomendasikan untuk menginstal plugin Wpcode.

    1.Registry Core (CPT & Hreflang):

    Mendaftarkan CPT English dan menyuntikkan meta tag <hreflang> agar Google mengenali relasi bahasa secara resmi.

    Tambahkan kode baru [php] berikut menggunakan snipet wpcode:

    <?php
    /**
     * WP Custom Multilingual CPT & Dynamic Hreflang
     * * Description: Registers English Custom Post Types (Articles & Pages) and 
     * dynamically injects SEO Hreflang tags and language attributes.
     * * @package     Pujashanti Language Core
     * @version     1.0.0
     * @author      Pujashanti (https://semaramedia.web.id/
     * @license     MIT License
     * * Copyright (c) 2026 Pujashanti
     * * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     * * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     */
    
    // 1. REGISTRASI TAXONOMY & CPT
    add_action('init', function() {
        // Kategori Inggris
        register_taxonomy('english_category', array('english_content'), array(
            'hierarchical'      => true,
            'labels'            => array('name' => 'Categories (EN)'),
            'public'            => true,
            'show_in_rest'      => true,
            'rewrite'           => array('slug' => 'en/topic', 'with_front' => false), 
        ));
    
        // Artikel Inggris
        register_post_type('english_content', array(
            'labels'             => array('name' => 'English Articles'),
            'public'             => true,
            'has_archive'        => 'en/articles', 
            'rewrite'            => array('slug' => 'en/articles', 'with_front' => false), 
            'menu_icon'          => 'dashicons-translation',
            'supports'           => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'),
            'show_in_rest'       => true,
            'taxonomies'         => array('english_category'),
        ));
    
        // Halaman Inggris
        register_post_type('english_page', array(
            'labels'             => array('name' => 'English Pages'),
            'public'             => true,
            'hierarchical'       => true,
            'rewrite'            => array('slug' => 'en', 'with_front' => false, 'pages' => true), 
            'menu_icon'          => 'dashicons-admin-page',
            'supports'           => array('title', 'editor', 'thumbnail', 'page-attributes', 'custom-fields'),
            'show_in_rest'       => true,
        ));
    }, 5);
    
    // 2. FUNGSI DETEKSI KONTEKS (Helper)
    if ( ! function_exists( 'ps_is_english_context' ) ) {
        /**
         * Checks if the current request is within the English language context.
         * @return boolean
         */
        function ps_is_english_context() {
            global $post;
            $en_types = array('english_content', 'english_page');
            $uri = $_SERVER['REQUEST_URI'] ?? '';
            if ( (isset($post) && in_array($post->post_type, $en_types)) || 
                 is_tax('english_category') || 
                 strpos($uri, '/en/') !== false ) {
                return true;
            }
            return false;
        }
    }
    
    // 3. DYNAMIC HREFLANG INJECTION
    add_action('wp_head', 'ps_dynamic_hreflang', 1);
    add_action('amp_post_template_head', 'ps_dynamic_hreflang', 1);
    function ps_dynamic_hreflang() {
        $current_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        
        if (ps_is_english_context()) {
            echo '<link rel="alternate" hreflang="en" href="' . esc_url($current_url) . '" />' . "\n";
            echo '<link rel="alternate" hreflang="id" href="https://semaramedia.web.id/" />' . "\n";
            echo '<link rel="alternate" hreflang="x-default" href="https://semaramedia.web.id/" />' . "\n";
        } else {
            echo '<link rel="alternate" hreflang="id" href="' . esc_url($current_url) . '" />' . "\n";
            echo '<link rel="alternate" hreflang="en" href="https://semaramedia.web.id/en/" />' . "\n";
            echo '<link rel="alternate" hreflang="x-default" href="' . esc_url($current_url) . '" />' . "\n";
        }
    }
    
    // 4. FORCE LANG ATTRIBUTE (HTML Lang Tag)
    add_action('template_redirect', function() {
        if (ps_is_english_context()) {
            ob_start(function($buffer) {
                $buffer = preg_replace('/lang="id(-|_)?[A-Z]*"/i', 'lang="en-US"', $buffer);
                return $buffer;
            });
        }
    }, 1);

    2. Rewrite English Home:

    Menghilangkan error 404 pada URL /en/ dan mendukung navigasi AMP.

    /**
     * SNIPPET 2: THE URL ENGINE & AMP FIX
     * Website: semaramedia.web.id/
     */
    
    // 1. REWRITE RULES (Jalur Sistem)
    add_action('init', function() {
        // Pastikan /en/ dan /en/amp/ mengarah ke halaman 'home' di English Pages
        add_rewrite_rule('^en/?$', 'index.php?english_page=home', 'top');
        add_rewrite_rule('^en/amp/?$', 'index.php?english_page=home&amp=1', 'top');
    }, 10);
    
    // 2. THE GHOST HOME LOGIC (Tanpa Redirect)
    add_action('parse_request', function($wp) {
        if (isset($wp->request) && $wp->request == 'en') {
            $wp->query_vars['english_page'] = 'home';
            $wp->query_vars['post_type'] = 'english_page';
            $wp->query_vars['name'] = 'home';
    
            add_filter('status_header', function($status, $code) {
                return ($code == 404) ? 'HTTP/1.1 200 OK' : $status;
            }, 10, 2);
    
            add_action('wp', function() {
                global $wp_query;
                if ($wp_query->is_404) {
                    $wp_query->is_404 = false;
                    $wp_query->is_single = true;
                    $wp_query->is_page = true;
                }
            });
        }
    });
    
    // 3. AMP INTEGRATION (Fix Mismatch & Canonical)
    add_filter('amp_post_status_default_enabled', function($enabled, $post) {
        if (isset($post->post_type) && in_array($post->post_type, ['english_page', 'english_content'])) return true;
        return $enabled;
    }, 10, 2);
    
    add_filter('amp_get_canonical_url', 'ps_fix_clean_canonical', 999);
    add_filter('ampforwp_canonical_url', 'ps_fix_clean_canonical', 999);
    function ps_fix_clean_canonical($url) {
        // Jika di halaman home english, paksa canonical ke /en/
        if (strpos($_SERVER['REQUEST_URI'], '/en/') !== false && (is_single('home') || is_front_page())) {
            return home_url('/en/');
        }
        return $url;
    }
    
    // 4. INJEKSI AMPHTML PADA DESKTOP /en/
    add_action('wp_head', function() {
        if (trim($_SERVER['REQUEST_URI'], '/') == 'en') {
            echo '<link rel="amphtml" href="' . home_url('/en/?amp=1') . '" />' . "\n";
        }
    }, 2);

    3. Custom Field Taxonomy:

    Menambahkan fitur input URL relasi khusus untuk editor kategori (Taxonomy) yang secara bawaan tidak didukung WordPress.

    /**
     * PUJASHANTI: UNIVERSAL TAXONOMY META INPUT
     * Otomatis muncul di Kategori Post, Tag, dan Taksonomi CPT English
     */
    
    add_action('admin_init', function() {
        // Ambil semua taksonomi yang ada di WordPress
        $taxonomies = get_taxonomies(); 
        
        foreach ( $taxonomies as $taxonomy ) {
            // Suntik Form Edit
            add_action($taxonomy . '_edit_form_fields', 'ps_taxonomy_edit_meta_fields', 10, 2);
            // Suntik Logika Simpan
            add_action('edited_' . $taxonomy, 'ps_save_taxonomy_meta', 10, 1);
        }
    });
    
    // Fungsi Form (Tetap sama, namun pastikan nama function sesuai)
    function ps_taxonomy_edit_meta_fields($term, $taxonomy) {
        $url_en = get_term_meta($term->term_id, 'url_en', true);
        $url_id = get_term_meta($term->term_id, 'url_id', true);
        ?>
        <tr class="form-field">
            <th scope="row"><label for="url_en">URL English (EN)</label></th>
            <td>
                <input type="url" name="url_en" id="url_en" value="<?php echo esc_url($url_en); ?>" placeholder="https://...">
                <p class="description">Link versi Inggris untuk taksonomi ini.</p>
            </td>
        </tr>
        <tr class="form-field">
            <th scope="row"><label for="url_id">URL Indonesia (ID)</label></th>
            <td>
                <input type="url" name="url_id" id="url_id" value="<?php echo esc_url($url_id); ?>" placeholder="https://...">
                <p class="description">Link versi Indonesia untuk taksonomi ini.</p>
            </td>
        </tr>
        <?php
    }
    
    // Fungsi Simpan (Universal)
    function ps_save_taxonomy_meta($term_id) {
        if (isset($_POST['url_en'])) {
            update_term_meta($term_id, 'url_en', esc_url_raw($_POST['url_en']));
        }
        if (isset($_POST['url_id'])) {
            update_term_meta($term_id, 'url_id', esc_url_raw($_POST['url_id']));
        }
    }

    4. Language Switcher Post & Page:

    Logika otomatis untuk mendeteksi relasi bahasa dan menampilkan tombol switcher di dalam konten.

    /**
     * SWITCHER 1: SINGLE POST / PAGE / CPT
     */
    add_action('wp_footer', function() {
        if ( is_admin() || !is_singular() || (function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint()) ) return;
    
        $id = get_the_ID();
        $url_en = get_post_meta($id, 'url_en', true);
        $url_id = get_post_meta($id, 'url_id', true);
    
        if ( empty($url_en) && empty($url_id) ) return;
        $label = !empty($url_en) ? 'ID' : 'EN';
        ?>
        <div class="ps-lang-wrapper">
            <div class="ps-lang-menu" id="psLangMenu">
                <?php if (!empty($url_en)) echo '<a href="'.esc_url($url_en).'">🇺🇸 English (EN)</a>'; ?>
                <?php if (!empty($url_id)) echo '<a href="'.esc_url($url_id).'">🇮🇩 Indonesia (ID)</a>'; ?>
            </div>
            <button type="button" class="ps-lang-toggle" onclick="togglePsLang()">
                <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>
                <span class="ps-code"><?php echo $label; ?></span> <span>Language</span>
            </button>
        </div>
        <?php
    });

    5. Language Switcher Khusus Taksonomi:

    Menangani navigasi bahasa khusus untuk halaman arsip/kategori agar tidak konflik dengan post biasa.

    /**
     * SWITCHER 2: TAXONOMY (CATEGORY / TAG)
     */
    add_action('wp_footer', function() {
        if ( is_admin() || (!is_category() && !is_tag() && !is_tax()) || (function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint()) ) return;
    
        $term_id = get_queried_object_id();
        $url_en = get_term_meta($term_id, 'url_en', true);
        $url_id = get_term_meta($term_id, 'url_id', true);
    
        if ( empty($url_en) && empty($url_id) ) return;
        $label = !empty($url_en) ? 'ID' : 'EN';
        ?>
        <div class="ps-lang-wrapper">
            <div class="ps-lang-menu" id="psLangMenu">
                <?php if (!empty($url_en)) echo '<a href="'.esc_url($url_en).'">🇺🇸 English (EN)</a>'; ?>
                <?php if (!empty($url_id)) echo '<a href="'.esc_url($url_id).'">🇮🇩 Indonesia (ID)</a>'; ?>
            </div>
            <button type="button" class="ps-lang-toggle" onclick="togglePsLang()">
                <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>
                <span class="ps-code"><?php echo $label; ?></span> <span>Language</span>
            </button>
        </div>
        <?php
    });

    6. Language Switcher Blog Index:

    Filter khusus untuk halaman daftar artikel (Blogpage) agar navigasi tetap konsisten.

    /**
     * SWITCHER 3: MAIN ARCHIVE (STATIC)
     */
    add_action('wp_footer', function() {
        if ( is_admin() || is_singular() || is_category() || is_tag() || is_tax() ) return;
    
        $uri = $_SERVER['REQUEST_URI'];
        $is_id = (strpos($uri, '/artikel/') !== false);
        $is_en = (strpos($uri, '/en/articles/') !== false);
    
        if ( !$is_id && !$is_en ) return;
        $label = $is_id ? 'ID' : 'EN';
        ?>
        <div class="ps-lang-wrapper">
            <div class="ps-lang-menu" id="psLangMenu">
                <?php if ($is_id) echo '<a href="https://semaramedia.web.id/en/articles/">🇺🇸 English (EN)</a>'; ?>
                <?php if ($is_en) echo '<a href="https://semaramedia.web.id/artikel/">🇮🇩 Indonesia (ID)</a>'; ?>
            </div>
            <button type="button" class="ps-lang-toggle" onclick="togglePsLang()">
                <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>
                <span class="ps-code"><?php echo $label; ?></span> <span>Language</span>
            </button>
        </div>
        <?php
    });

    7. CSS All-in-One Switcher:

    Desain visual seragam untuk semua tombol switcher (Desktop & Mobile).

    /**
     * SHARED ASSETS: CSS & JS
     */
    add_action('wp_footer', function() { ?>
        <script>
            function togglePsLang() {
                var m = document.getElementById("psLangMenu");
                if(m) m.classList.toggle("show");
            }
            window.onclick = function(e) {
                if (!e.target.closest('.ps-lang-wrapper')) {
                    var m = document.getElementById("psLangMenu");
                    if(m) m.classList.remove('show');
                }
            }
        </script>
        <style>
        /* Kontainer Utama */
        .ps-lang-wrapper { 
            position: fixed; 
            bottom: 120px; /* Posisi default (Desktop) - di atas anchor/tombol back to top */
            right: 20px; 
            z-index: 999999; /* Z-index sangat tinggi agar tidak tertutup elemen lain */
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        }
    
        /* Tombol Switcher */
        .ps-lang-toggle { 
            background: #ffffff; 
            border: 1.5px solid #2c3e50; 
            padding: 8px 14px; 
            border-radius: 50px; 
            cursor: pointer; 
            display: flex; 
            align-items: center; 
            box-shadow: 0 4px 12px rgba(0,0,0,0.15); 
            transition: all 0.2s ease;
        }
    
        .ps-lang-toggle:hover {
            background: #f8f9fa;
            transform: translateY(-2px);
        }
    
        .ps-lang-toggle svg {
            color: #2c3e50;
        }
    
        .ps-lang-toggle .ps-code { 
            font-weight: 800; 
            margin: 0 6px; 
            color: #2c3e50; 
            font-size: 14px;
            border-right: 1px solid #ddd;
            padding-right: 6px;
        }
    
        .ps-lang-toggle span:last-child {
            font-size: 12px;
            color: #666;
            font-weight: 600;
            text-transform: uppercase;
        }
    
        /* Menu Drop-up */
        .ps-lang-menu { 
            display: none; 
            position: absolute; 
            bottom: 55px; 
            right: 0; 
            background: #ffffff; 
            border: 1px solid #ddd; 
            border-radius: 12px; 
            min-width: 180px; 
            box-shadow: 0 10px 25px rgba(0,0,0,0.2); 
            overflow: hidden;
            animation: psFadeInUp 0.3s ease;
        }
    
        @keyframes psFadeInUp {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
    
        .ps-lang-menu.show { display: block; }
    
        .ps-lang-menu a { 
            display: block; 
            padding: 12px 18px; 
            text-decoration: none; 
            color: #333; 
            border-bottom: 1px solid #f0f0f0; 
            font-size: 14px; 
            font-weight: 500;
            transition: background 0.2s;
        }
    
        .ps-lang-menu a:last-child { border: none; }
        .ps-lang-menu a:hover { background: #f1f3f5; color: #2c3e50; }
    
        /* RESPONSIVE: KHUSUS MOBILE (Menghindari Iklan Anchor 80px) */
        @media screen and (max-width: 768px) {
            .ps-lang-wrapper { 
                bottom: 120px; /* Jarak aman di atas iklan anchor 80px */
                right: 15px;
            }
            .ps-lang-toggle {
                padding: 6px 12px;
            }
            .ps-lang-toggle span:last-child {
                display: none; /* Sembunyikan teks "Language" di mobile agar ringkas, sisakan ikon & ID/EN */
            }
            .ps-lang-toggle .ps-code {
                border-right: none;
                margin-right: 0;
                padding-right: 0;
            }
        }
    </style>
    <?php }, 100);

    8. CSS Khusus AMP:

    Kode gaya yang sudah difilter agar lolos validasi ketat sistem AMP.

    /**
     * 1. CSS KHUSUS AMPFORWP (Suntik ke Head)
     * Penempatan: Pojok Kanan Bawah (Floating)
     */
    add_action('amp_post_template_css', function() {
        ?>
        /* Container Switcher - Melayang di Kanan Bawah */
        .ps-amp-top-switcher {
            position: fixed !important;
            bottom: 120px !important; /* Jarak 70px dari tepi bawah (di atas Social Share) */
            right: 15px !important; /* Jarak dari tepi kanan */
            z-index: 999999 !important;
            display: block !important;
            background: transparent !important;
            pointer-events: none !important;
            top: auto !important; /* Mematikan setting top sebelumnya */
        }
    
        /* Tombol ID/EN Kapsul Modern */
        .ps-amp-top-btn {
            pointer-events: auto !important;
            display: inline-block !important;
            background-color: #ffffff !important;
            color: #003366 !important; /* Navy Pujashanti */
            padding: 10px 18px !important;
            border-radius: 50px !important;
            font-size: 13px !important;
            font-weight: 800 !important;
            text-decoration: none !important;
            border: 2px solid #b38b4d !important; /* Border Emas */
            box-shadow: 0 6px 15px rgba(0,0,0,0.3) !important;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
            line-height: 1 !important;
            white-space: nowrap !important;
            transition: transform 0.2s ease !important;
        }
    
        /* Efek Klik */
        .ps-amp-top-btn:active {
            transform: scale(0.9) !important;
        }
        <?php
    });
    
    /**
     * 2. HTML SWITCHER (Suntik Setelah Header)
     * Menggunakan hook internal AMPforWP
     */
    add_action('ampforwp_after_header', 'ps_header_switcher_bottom_safe');
    function ps_header_switcher_bottom_safe() {
        $post_id = get_the_ID();
        $current_uri = $_SERVER['REQUEST_URI'];
        $link = '';
    
        // Logika deteksi URL English menggunakan Meta Data
        if (strpos($current_uri, '/en/') !== false) {
            $url_id = get_post_meta($post_id, 'url_id', true);
            if ($url_id) {
                $link = '<a href="' . esc_url($url_id) . '?amp=1" class="ps-amp-top-btn">🇮🇩 INDONESIA</a>';
            }
        } else {
            $url_en = get_post_meta($post_id, 'url_en', true);
            if ($url_en) {
                $link = '<a href="' . esc_url($url_en) . '?amp=1" class="ps-amp-top-btn">🇺🇸 ENGLISH</a>';
            }
        }
    
        if ($link) {
            echo '<div class="ps-amp-top-switcher">' . $link . '</div>';
        }
    }

    9. Language Switcher Khusus AMPforWP:

    Optimasi akhir agar navigasi bahasa berjalan sempurna di ekosistem AMP.

    /**
     * 1. CSS KHUSUS AMPFORWP (Suntik ke Head)
     * Penempatan: Pojok Kanan Bawah (Floating)
     */
    add_action('amp_post_template_css', function() {
        ?>
        /* Container Switcher - Melayang di Kanan Bawah */
        .ps-amp-top-switcher {
            position: fixed !important;
            bottom: 120px !important; /* Jarak 70px dari tepi bawah (di atas Social Share) */
            right: 15px !important; /* Jarak dari tepi kanan */
            z-index: 999999 !important;
            display: block !important;
            background: transparent !important;
            pointer-events: none !important;
            top: auto !important; /* Mematikan setting top sebelumnya */
        }
    
        /* Tombol ID/EN Kapsul Modern */
        .ps-amp-top-btn {
            pointer-events: auto !important;
            display: inline-block !important;
            background-color: #ffffff !important;
            color: #003366 !important; /* Navy Pujashanti */
            padding: 10px 18px !important;
            border-radius: 50px !important;
            font-size: 13px !important;
            font-weight: 800 !important;
            text-decoration: none !important;
            border: 2px solid #b38b4d !important; /* Border Emas */
            box-shadow: 0 6px 15px rgba(0,0,0,0.3) !important;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
            line-height: 1 !important;
            white-space: nowrap !important;
            transition: transform 0.2s ease !important;
        }
    
        /* Efek Klik */
        .ps-amp-top-btn:active {
            transform: scale(0.9) !important;
        }
        <?php
    });
    
    /**
     * 2. HTML SWITCHER (Suntik Setelah Header)
     * Menggunakan hook internal AMPforWP
     */
    add_action('ampforwp_after_header', 'ps_header_switcher_bottom_safe');
    function ps_header_switcher_bottom_safe() {
        $post_id = get_the_ID();
        $current_uri = $_SERVER['REQUEST_URI'];
        $link = '';
    
        // Logika deteksi URL English menggunakan Meta Data
        if (strpos($current_uri, '/en/') !== false) {
            $url_id = get_post_meta($post_id, 'url_id', true);
            if ($url_id) {
                $link = '<a href="' . esc_url($url_id) . '?amp=1" class="ps-amp-top-btn">🇮🇩 INDONESIA</a>';
            }
        } else {
            $url_en = get_post_meta($post_id, 'url_en', true);
            if ($url_en) {
                $link = '<a href="' . esc_url($url_en) . '?amp=1" class="ps-amp-top-btn">🇺🇸 ENGLISH</a>';
            }
        }
    
        if ($link) {
            echo '<div class="ps-amp-top-switcher">' . $link . '</div>';
        }
    }

    Setelah semua kode dan halaman siap, Anda WAJIB melakukan reset permalink. Jika tidak, struktur URL baru Anda akan menemui error 404.

    Cara Melakukannya:

    1. Buka menu Settings (Pengaturan) > Permalinks.
    2. Tanpa mengubah pengaturan apapun, klik tombol Save Changes (Simpan Perubahan).
    3. Ulangi sekali lagi (Total 2x klik simpan).

    Mengapa harus 2 kali?

    Langkah ini memaksa WordPress menghapus cache struktur URL lama dan menulis ulang (flush) aturan navigasi yang baru ke dalam file .htaccess. Pengulangan kedua memastikan sistem benar-benar telah menyinkronkan seluruh aturan Rewrite URL dari Custom Post Type yang baru saja kita buat.

    Halaman ini tidak mendukung versi amp

    Lihat Juga

  • Cara Membuat WordPress Multi bahasa Tanpa Plugin WPML & Polylang

    Cara Membuat WordPress Multi bahasa Tanpa Plugin WPML & Polylang


    WordPress Multi bahasa

    Panduan Pro: Membuat WordPress Multi-Bahasa Tanpa Plugin (WPML/Polylang)

    Cara Membuat WordPress Multi bahasa Tanpa Plugin WPML & Polylang: Memiliki situs multi bahasa seringkali menjadi dilema bagi pengembang web. Plugin populer seperti WPML atau Polylang memang memudahkan, namun mereka sering kali menyisakan “sampah” database yang besar dan membebani server (overhead).

    Keunggulan Metode Custom Post Type (CPT)

    Dengan menggunakan metode Custom Post Type, kita menciptakan struktur yang jauh lebih bersih bagi Situs web. Keunggulannya antara lain:

    • Database Sangat Ringan: Tidak ada tabel tambahan yang tidak perlu.
    • Kecepatan Server Maksimal: Mengurangi beban PHP saat memproses halaman (Sangat baik untuk skor PSI).
    • Kontrol Penuh: Anda memegang kendali atas struktur URL dan logika relasi antar bahasa.

    Langkah Persiapan & Lingkungan Kerja

    Sebelum mengeksekusi kode, pastikan lingkungan kerja Anda sudah siap:

    • Plugin WPCODE (Sangat Direkomendasikan): Gunakan ini untuk menginjeksi kode tanpa menyentuh functions.php. Ini menjaga kode tetap aman saat tema diperbarui dan menghindari risiko conflict.
    • Theme Twenty Twenty-Five: Tema ini memberikan fleksibilitas penuh untuk kustomisasi template tanpa batasan fitur.
    • Plugin AMPforWP (Opsional): Sistem ini sudah diuji stabil untuk membuat halaman versi AMP yang super cepat.

    Catatan: Kode lengkap untuk sistem ini bisa Anda temukan di halaman Kumpulan Snippet WPCODE. Pastikan Anda menyalinnya dari sana sebelum memulai langkah di bawah ini.


    Langkah-Langkah Implementasi Konten

    Setelah kode diinjeksi melalui WPCODE, ikuti langkah operasional berikut untuk mulai membangun konten multi-bahasa:

    1. Menyiapkan Homepage Versi Inggris

    Agar URL root bahasa Inggris (/en/) berfungsi sebagai beranda, Anda perlu melakukan langkah berikut:

    • Buatlah sebuah halaman baru di dalam CPT English Page.
    • Berikan slug URL: /home/.
    • Logika Sistem: Kode rewrite URL yang telah dipasang akan secara otomatis mengenali slug ini dan mengalihkan (redirect) alamat /en/home/ menjadi URL cantik /en/.

    2. Membuat Artikel atau Halaman Inggris Baru

    Untuk mengisi konten internasional, cari menu English Articles atau English Pages di dashboard WordPress Anda:

    • Tambahkan post/page baru seperti biasa.
    • Penting: Pada panel Custom Field, tambahkan meta data relasi:
      • Gunakan key url_en jika Anda berada di editor halaman Indonesia.
      • Gunakan key url_id jika Anda berada di editor halaman Inggris.
    • Isikan nilai (value) berupa URL lengkap halaman pasangannya. Inilah yang menjadi “jembatan” bagi Language Switcher untuk bekerja.

    Bedah Arsitektur: 9 Engine Multi-Language

    Berikut adalah fungsi dari masing-masing kode yang akan Anda pasang:

    1. Registry Core (CPT & Hreflang): Mendaftarkan CPT English dan menyuntikkan meta tag <hreflang> agar Google mengenali relasi bahasa secara resmi.
    2. Rewrite English Home: Menghilangkan error 404 pada URL /en/ dan mendukung navigasi AMP.
    3. Custom Field Taxonomy: Menambahkan fitur input URL relasi khusus untuk editor kategori (Taxonomy) yang secara bawaan tidak didukung WordPress.
    4. Language Switcher Post & Page: Logika otomatis untuk mendeteksi relasi bahasa dan menampilkan tombol switcher di dalam konten.
    5. Language Switcher Khusus Taksonomi: Menangani navigasi bahasa khusus untuk halaman arsip/kategori agar tidak konflik dengan post biasa.
    6. Language Switcher Blog Index: Filter khusus untuk halaman daftar artikel (Blogpage) agar navigasi tetap konsisten.
    7. CSS All-in-One Switcher: Desain visual seragam untuk semua tombol switcher (Desktop & Mobile).
    8. CSS Khusus AMP: Kode gaya yang sudah difilter agar lolos validasi ketat sistem AMP.
    9. Language Switcher Khusus AMPforWP: Optimasi akhir agar navigasi bahasa berjalan sempurna di ekosistem AMP.

    Setelah semua kode dan halaman siap, Anda WAJIB melakukan reset permalink. Jika tidak, struktur URL baru Anda akan menemui error 404.

    Cara Melakukannya:

    1. Buka menu Settings (Pengaturan) > Permalinks.
    2. Tanpa mengubah pengaturan apapun, klik tombol Save Changes (Simpan Perubahan).
    3. Ulangi sekali lagi (Total 2x klik simpan).

    Mengapa harus 2 kali?

    Langkah ini memaksa WordPress menghapus cache struktur URL lama dan menulis ulang (flush) aturan navigasi yang baru ke dalam file .htaccess. Pengulangan kedua memastikan sistem benar-benar telah menyinkronkan seluruh aturan Rewrite URL dari Custom Post Type yang baru saja kita buat.


    Dokumentasi Teknis: Custom Multilingual & Context-Aware Hreflang

    1. Pendahuluan

    Snippet ini dirancang untuk pengguna WordPress yang ingin memiliki sistem multibahasa (Indonesia – Inggris) tanpa menggunakan plugin berat seperti WPML atau Polylang. Kode ini bekerja dengan cara mendaftarkan Custom Post Type (CPT) khusus untuk konten Inggris dan mengelola tag meta SEO secara otomatis berdasarkan konteks URL.

    2. Logika Kerja Kode

    Snippet ini dibagi menjadi empat bagian utama yang saling terintegrasi:

    A. Registrasi CPT & Taxonomy (init)

    Sistem menciptakan “ruang kerja” baru di dashboard:

    • English Articles (english_content): Dengan slug /en/articles/.
    • English Pages (english_page): Dengan slug /en/.
    • Categories EN (english_category): Dengan slug /en/topic/.
    • Keunggulan: Memisahkan database konten bahasa agar struktur URL tetap bersih (SEO-friendly).

    B. Deteksi Konteks (ps_is_english_context)

    Ini adalah “otak” dari snippet ini. Fungsi ini memeriksa apakah halaman yang sedang diakses adalah bagian dari konten Inggris dengan mengecek:

    1. Apakah tipe postingan termasuk dalam CPT Inggris?
    2. Apakah sedang membuka kategori bahasa Inggris?
    3. Apakah URL mengandung folder /en/?

    C. Injeksi Dynamic Hreflang (wp_head)

    Hreflang sangat krusial agar Google tidak menganggap konten Anda sebagai duplikat.

    • Jika konteks English: Sistem memberikan tag hreflang=”en” pada URL tersebut dan hreflang=”id” pada root.
    • Jika konteks Indonesia: Sistem memberikan tag hreflang=”id” pada URL tersebut dan hreflang=”en” pada halaman utama /en/.
    • Dilengkapi dengan x-default sebagai sinyal bahasa utama global.

    D. Manipulasi Output Buffer (template_redirect)

    WordPress hanya mengizinkan satu bahasa utama di pengaturan Settings > General. Snippet ini melakukan interupsi pada output HTML untuk mengganti atribut lang=”id-ID” menjadi lang=”en-US” (atau sebaliknya) secara otomatis saat halaman dimuat, sehingga browser dan mesin pencari mendeteksi bahasa yang tepat.


    3. Skenario Bahasa Default (Penting)

    Kode ini bersifat adaptif. Berikut adalah hal yang perlu diperhatikan terkait pengaturan bahasa di dashboard WordPress:

    Jika Default WordPress adalah…Maka Snippet Akan…
    Bahasa Indonesia (Default)Membiarkan konten utama tetap ID, dan mengubah konten di /en/ menjadi EN.
    English (US)Anda harus membalik logika pada Bagian 4 agar sistem mengubah konten utama menjadi ID, sementara konten /en/ tetap EN.

    Lisensi: Kode ini dirilis di bawah MIT License. Anda bebas menggunakan, memodifikasi, dan mendistribusikannya selama menyertakan atribusi penulis asli.


    Penutup

    Dengan metode tanpa plugin ini, situs anda akan tetap ringan, memiliki performa SEO yang solid, dan memberikan pengalaman pengguna yang mulus tanpa ketergantungan pada plugin pihak ketiga yang berat. Selamat mencoba!

    FAQ: WordPress Multi-Bahasa Tanpa Plugin

    Mengapa metode CPT lebih baik daripada plugin WPML atau Polylang? +
    Metode Custom Post Type (CPT) jauh lebih ringan karena tidak menambah tabel baru pada database. Ini menjaga performa server tetap stabil dan skor PageSpeed Insights (PSI) tetap tinggi karena tidak ada beban skrip pihak ketiga yang berat.
    Bagaimana cara menghubungkan artikel Indonesia dengan versi Inggris? +
    Anda cukup menggunakan panel Custom Fields pada editor post. Tambahkan key url_en pada artikel Indonesia dan isi dengan URL versi Inggrisnya. Lakukan hal sebaliknya (key url_id) pada artikel Inggris.
    Apakah sistem ini aman untuk halaman versi AMP? +
    Ya, kode ini telah diuji secara khusus agar kompatibel dengan plugin AMPforWP. Kami juga menyertakan CSS khusus AMP agar navigasi bahasa tetap valid dan tidak menyebabkan error pada sistem validasi AMP yang ketat.
    Mengapa saya harus melakukan reset permalink sebanyak dua kali? +
    Reset permalink (Save 2x) sangat krusial untuk melakukan flush rewrite rules. Langkah ini memaksa WordPress menghapus cache struktur URL lama dan mendaftarkan slug CPT baru (/en/) ke dalam sistem agar tidak terjadi error 404.
    Dimana saya bisa mendapatkan kode lengkap untuk tutorial ini? +
    Seluruh kode (9 bagian MULTILANG Engine) dapat Anda temukan dan salin langsung melalui halaman Kumpulan Snippet WPCODE di situs ini.

  • Plugin Custom Animation Bundle (CAB) PUJASHANTI

    Plugin Custom Animation Bundle (CAB) PUJASHANTI

    Panduan Penggunaan Plugin Custom Animation Bundle (CAB)

    Panduan Penggunaan Plugin Custom Animation Bundle (CAB)

    Versi: 1.1.3 (Updated 2026) Panduan Penggunaan Plugin Custom Animation Bundle (CAB). Pustaka ini dirancang untuk memberikan efek visual yang ringan, berperforma tinggi, dan ramah SEO pada website WordPress Anda.

    1. Struktur Class Dasar

    Setiap elemen yang ingin diberi animasi harus memiliki minimal dua class utama:

    • cab-anim: Class wajib yang menyiapkan elemen (mengatur opacity 0 agar tidak terjadi kedipan saat halaman dimuat).
    • Class Efek: Menentukan jenis gerakan yang diinginkan.

    2. Daftar Efek Animasi

    Anda dapat memilih salah satu dari efek berikut:

    KategoriClassDeskripsi Gerakan
    Fadecab-fade-inMuncul perlahan di tempat.
    cab-fade-upMuncul perlahan sambil bergerak ke atas.
    Zoomcab-zoom-inMembesar dari titik tengah.
    cab-zoom-upMembesar sambil bergerak ke atas.
    Slidecab-slide-leftMuncul dari arah kiri.
    cab-slide-rightMuncul dari arah kanan.
    cab-slide-topMuncul dari atas ke bawah.
    cab-slide-bottomMuncul dari bawah ke atas.
    Attentioncab-pulseEfek berdenyut terus-menerus (looping).

    3. Pengaturan Jeda (Delay) & Kecepatan

    Untuk membuat efek berurutan (staggered), gunakan class utilitas berikut:

    • Jeda Standar (CSS):
      • cab-delay-1 s/d cab-delay-5 (Jeda 0.1 detik hingga 0.5 detik).
    • Jeda & Durasi Kustom (Dinamis via JS):
      • cab-delay-[angka]ms: Contoh cab-delay-750ms.
      • cab-duration-[angka]ms: Contoh cab-duration-2000ms.

    4. Contoh Implementasi Kode

    Salin contoh berikut ke dalam editor HTML WordPress atau Page Builder Anda:

    Contoh Animasi:

    Fitur A
    Fitur B
    Fitur C
    Teks ini muncul sangat lembut setelah 0.8 detik.

    HTML

    <div class="column cab-anim cab-fade-up cab-delay-1" style="background-color: blue; text-align: center; color: white; border-radius: 5px; margin: 10px 20px; 20px">Fitur A</div>
    <div class="column cab-anim cab-fade-up cab-delay-2" style="background-color: green; text-align: center; color: white; border-radius: 5px; margin: 10px 20px;">Fitur B</div>
    <div class="column cab-anim cab-fade-up cab-delay-3" style="background-color: green; text-align: center; color: white; border-radius: 5px; margin: 10px 20px;">Fitur C</div>
    
    <div class="cab-anim cab-zoom-in cab-delay-800ms cab-slow" style="background-color: blue; text-align: center; color: white; border-radius: 5px; margin: 10px 20px; 20px;">
       Teks ini muncul sangat lembut setelah 0.8 detik.
    </div>

    5. Catatan Teknis & Performa

    • Intersection Observer: Animasi hanya akan berjalan saat elemen masuk ke area layar (viewport) untuk menghemat baterai perangkat mobile.
    • Akselerasi GPU: Menggunakan translate3d untuk memastikan gerakan tetap mulus pada 60fps.
    • Aksesibilitas: Animasi otomatis mati jika pengguna mengaktifkan fitur “Reduce Motion” di sistem operasi mereka.

    Panduan Implementasi Animasi CAB

    Versi: 1.1.3

    Fungsi animasi CAB dirancang agar fleksibel dan dapat diterapkan melalui dua metode utama di dalam editor WordPress:

    Metode 1: Menambahkan Class pada Blok HTML Kustom

    Metode ini digunakan jika Anda membangun elemen secara manual menggunakan blok Custom HTML. Ini memberikan kontrol penuh atas struktur elemen.

    Langkah-langkah:

    1. Masukkan blok Custom HTML di editor halaman Anda.
    2. Tambahkan class wajib .cab-anim diikuti oleh class efek dan jeda (delay).
    3. Contoh Kode:
    <div class="cab-anim cab-fade-up cab-delay-1">
        <h3>Judul Animasi</h3>
        <p>Konten ini akan muncul dengan efek fade-up.</p>
    </div>

    Metode 2: Menambahkan Class melalui Pengaturan Blok (Gutenberg/Elementor)

    Metode ini adalah cara termudah bagi pengguna yang menggunakan blok standar WordPress (seperti Gambar, Judul, atau Paragraf) atau Page Builder.

    Langkah-langkah:

    1. Klik pada blok yang ingin Anda beri animasi (misalnya blok Image atau Heading).
    2. Buka panel pengaturan di sisi kanan layar (Tab Block).
    3. Gulir ke bawah hingga menemukan menu Advanced (Tingkat Lanjut).
    4. Pada kolom Additional CSS Class(es), masukkan kombinasi class animasi tanpa titik, dipisahkan dengan spasi.
    5. Contoh Pengisian:

    cab-anim cab-slide-bottom cab-delay-2


    Tabel Referensi Class Utama

    Gunakan kombinasi class berikut sesuai kebutuhan visual Anda:

    Jenis EfekNama Class (Pilih Satu)Class Jeda (Opsional)
    Fadecab-fade-in, cab-fade-upcab-delay-1 (0.1s)
    Zoomcab-zoom-in, cab-zoom-upcab-delay-2 (0.2s)
    Slidecab-slide-left, cab-slide-rightcab-delay-3 (0.3s)
    Vertical Slidecab-slide-top, cab-slide-bottomcab-delay-500ms (Kustom)

    Tips Pro: Anda dapat menggabungkan class durasi kustom seperti cab-duration-2000ms di kolom class tambahan untuk membuat gerakan yang lebih dramatis dan lambat.


    Cara memasang plugin

    Berikut adalah panduan praktis untuk menginstal Custom Animation Bundle (CAB) PUJASHANTI melalui Dashboard WordPress. Plugin ini dirancang agar sangat ringan dan tidak membebani server Anda karena hanya menjalankan animasi saat elemen terlihat di layar.


    Panduan Instalasi Plugin CAB

    Custom Animation Bundle

    Versi 1.1.3

    Library animasi super ringan yang dirancang untuk performa tinggi tanpa membebani server Anda[cite: 3]. Menggunakan teknologi Intersection Observer untuk efisiensi baterai dan CPU[cite: 2, 3].

    • ✦ Ringan & Cepat (High Performance) [cite: 3]
    • ✦ Mobile & SEO Friendly [cite: 3]
    • ✦ No-Code Implementation
    Cara Instalasi (3 Langkah Cepat)
    1. Unduh file .zip melalui tombol di atas.
    2. Buka Dashboard WordPress > Plugins > Add New.
    3. Klik Upload Plugin, pilih file, dan Aktifkan.

    1. Persiapkan File Plugin

    • Pastikan Anda telah mengunduh file plugin dalam format .zip.
    • Jangan mengekstrak file tersebut di komputer Anda; biarkan dalam format .zip agar bisa dibaca oleh sistem pengunggah WordPress.

    2. Unggah Melalui Dashboard WordPress

    • Masuk ke Dashboard Admin WordPress Anda.
    • Buka menu Plugins > Add New (Tambah Baru).
    • Klik tombol Upload Plugin (Unggah Plugin) yang terletak di bagian atas halaman.
    • Klik Choose File (Pilih File) dan pilih file .zip yang telah Anda siapkan tadi.
    • Klik tombol Install Now (Instal Sekarang).

    3. Aktivasi Plugin

    • Setelah proses unggah selesai, WordPress akan menampilkan pesan konfirmasi.
    • Klik tombol Activate Plugin (Aktifkan Plugin) untuk mulai menggunakan fitur animasi di website Anda.

    Cara Memastikan Plugin Sudah Terpasang

    • Cek daftar plugin aktif Anda; pastikan Custom Animation Bundle sudah muncul dengan versi terbaru.
    • Plugin ini secara otomatis akan memuat file animations.css dan anim-handler.js ke front-end website Anda dengan sistem Anti-Cache untuk memastikan performa maksimal.
  • Demo plugin Animasi (CAB) PUJASHANTI

    Demo plugin Animasi (CAB) PUJASHANTI

    logo 2 pujashanti
    Demo CAB PUJASHANTI v1.1.3

    CAB Animation Demo v1.1.0

    Fade & Zoom Effects

    Fade In .cab-fade-in
    Fade Up .cab-fade-up
    Zoom In .cab-zoom-in
    Zoom Up .cab-zoom-up

    Scroll kebawah untuk melihat efek Slide…

    Slide Directions (Fixed Logic)

    Slide Left .cab-slide-left
    Slide Right .cab-slide-right
    Slide Top (Down) Meluncur dari atas kebawah. .cab-slide-top
    Slide Bottom (Up) Meluncur dari bawah keatas. .cab-slide-bottom

    Staggered Delay (Sequential)

    Delay 1 .cab-delay-1 (0.1s)
    Delay 2 .cab-delay-2 (0.2s)
    Delay 3 .cab-delay-3 (0.3s)
    Delay 4 .cab-delay-4 (0.4s)

    Custom Dynamic (JS Powered)

    Custom Jeda & Durasi .cab-delay-1000ms .cab-duration-2000ms
    Attention Seeker Bergetar terus menerus. .cab-pulse (Infinite)

  • Tutorial Cara Membuat Audio Player html WordPress Elegan dan Responsif

    Tutorial Cara Membuat Audio Player html WordPress Elegan dan Responsif


    Tutorial Cara Membuat Audio Player html WordPress Elegan dan Responsif

    Dalam panduan berikut ini, Cara Membuat Audio Player html WordPress Elegan dan Responsif, kita akan membuat Audio Player html wordpress modern dan responsif dengan fitur playlist dinamis, kontrol volume, dan desain sticky yang tetap muncul saat halaman di-scroll. Tutorial ini dikembangkan dengan bantuan Gemini Partner Code.

    Tutorial: Membuat Audio Player html WordPress Elegan & Responsif

    PUJASHANTI Audio Player
    Cover
    NOW PLAYING
    Memuat…

    Artis

    0:00 0:00

    Contoh Audio Player html wordpress

    Fitur Utama

    • Sticky Mode: Player tetap menempel di posisi atas layar.
    • Playlist Dinamis: Kelola daftar lagu melalui file JavaScript terpisah.
    • Custom Controls: Navigasi (Prev, Play, Next), Mute, dan Volume Slider.
    • FontAwesome Icons: Menggunakan ikon vektor profesional.
    • Atribusi Khusus: Footer khusus untuk brand PujaShanti.

    Langkah 1 Membuat Audio Player html: Menyiapkan Data Lagu (playlist-data.js)

    Buat file bernama playlist-data.js. File ini berfungsi sebagai database lagu Anda. Unggah ke Media Library WordPress dan catat URL-nya.

    Salin kode JavaScript

    const songs = [
        {
            title: "Judul Lagu 1",
            artist: "Nama Artis",
            src: "URL_FILE_AUDIO_DI_WORDPRESS",
            cover: "URL_FILE_GAMBAR_COVER"
        },
        {
            title: "Judul Lagu 2",
            artist: "Nama Artis",
            src: "URL_FILE_AUDIO_2",
            cover: "URL_FILE_COVER_2"
        }
    ];
    

    Langkah 2 Membuat Audio Player html: Menyiapkan Logika Player (player-logic.js)

    Buat file bernama player-logic.js. Ini adalah otak yang mengatur jalannya musik, navigasi, dan kontrol volume. Unggah file ini ke Media Library WordPress.

    Salin kode JavaScript

    document.addEventListener('DOMContentLoaded', function() {
        const audio = document.getElementById('wp-main-audio');
        const playBtn = document.getElementById('play-btn');
        const prevBtn = document.getElementById('prev-btn');
        const nextBtn = document.getElementById('next-btn');
        const muteBtn = document.getElementById('mute-btn');
        const volumeSlider = document.getElementById('volume-slider');
        const progress = document.getElementById('progress-bar');
        const progressContainer = document.getElementById('progress-container');
        const playlistElement = document.getElementById('wp-playlist-dynamic');
        
        let songIndex = 0;
    
        // Fungsi Update Ikon Volume
        function updateVolumeIcon(vol, isMuted) {
            if (isMuted || vol == 0) {
                muteBtn.innerHTML = '<i class="fas fa-volume-mute"></i>';
            } else {
                muteBtn.innerHTML = '<i class="fas fa-volume-up"></i>';
            }
        }
    
        // Fungsi Load Lagu
        function loadAndPlay() {
            const song = songs[songIndex];
            audio.src = song.src;
            document.getElementById('current-title').innerText = song.title;
            document.getElementById('current-artist').innerText = song.artist;
            document.getElementById('current-thumb').src = song.cover;
            audio.play();
            playBtn.innerHTML = '<i class="fas fa-pause"></i>';
        }
    
        // Event Listener lainnya (Next, Prev, Mute, Progress)...
        // (Gunakan kode logic versi final sebelumnya)
    });
    

    Langkah 3: Memasang Kode di WordPress

    Buka halaman atau postingan WordPress Anda, tambahkan blok Custom HTML, dan tempelkan kode berikut. Jangan lupa ganti URL script di bagian bawah dengan URL file yang sudah Anda unggah.

    Salin kode HTML

    
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>PUJASHANTI Audio Player</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
        
        <style>
            /* Layout Utama */
            .sticky-player { position: sticky; top: 20px; z-index: 999; }
            .elegant-player { 
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
                background: #111; 
                color: #fff; 
                border-radius: 20px; 
                overflow: hidden; 
                max-width: 380px; 
                margin: 40px auto; 
                box-shadow: 0 20px 50px rgba(0,0,0,0.8); 
                border: 1px solid #222; 
            }
            
            /* Header & Cover */
            .player-header { padding: 30px 20px; text-align: center; background: linear-gradient(180deg, #222, #111); }
            .album-art { width: 140px; height: 140px; margin: 0 auto 15px; border-radius: 15px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.5); border: 2px solid #333; }
            .album-art img { width: 100%; height: 100%; object-fit: cover; }
            .status-badge { font-size: 9px; color: #3498db; border: 1px solid #3498db; padding: 2px 10px; border-radius: 20px; letter-spacing: 1px; font-weight: bold; }
            #current-title { margin: 15px 0 5px; font-size: 1.2em; font-weight: 500; color: #fff; }
            #current-artist { color: #777; font-size: 0.9em; margin: 0; }
    
            /* Kontrol & Progress */
            .custom-controls { padding: 0 25px 25px; }
            .progress-container { background: #333; height: 6px; border-radius: 10px; cursor: pointer; margin-top: 10px; }
            .progress-bar { background: #3498db; height: 100%; width: 0%; border-radius: 10px; transition: width 0.1s linear; }
            .time-info { display: flex; justify-content: space-between; font-size: 11px; color: #555; margin: 8px 0 20px; }
    
            .main-btns { display: flex; justify-content: center; align-items: center; gap: 25px; }
            .main-btns button { background: none; border: none; color: #fff; cursor: pointer; font-size: 1.4rem; transition: 0.3s; padding: 10px; }
            .main-btns button:hover { color: #3498db; transform: scale(1.1); }
            
            /* Play Button (Khusus ID: play-btn) */
            #play-btn { 
                background: #3498db; 
                width: 60px; 
                height: 60px; 
                border-radius: 50%; 
                display: flex; 
                align-items: center; 
                justify-content: center;
                box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3); 
            }
            #play-btn:hover { background: #2980b9; }
    
            /* Volume Control */
            .volume-control-group { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 25px; }
            #mute-btn { background: none; border: none; color: #fff; cursor: pointer; font-size: 1.1rem; width: 30px; }
            #volume-slider { width: 80px; accent-color: #3498db; cursor: pointer; height: 4px; }
    
            /* Playlist (Target: wp-playlist-dynamic) */
            .playlist-container { max-height: 180px; overflow-y: auto; background: #0a0a0a; border-top: 1px solid #1a1a1a; list-style: none; padding: 0; margin: 0; }
            .wp-track { padding: 12px 25px; border-bottom: 1px solid #151515; cursor: pointer; transition: 0.2s; display: flex; flex-direction: column; }
            .wp-track:hover { background: #111; }
            .wp-track.active { border-left: 4px solid #3498db; background: #161616; }
            .track-name { display: block; font-size: 0.95em; color: #eee; font-weight: 500; }
            .track-artist { font-size: 0.8em; color: #555; }
    
            /* Footer */
            .player-footer { padding: 12px; background: #050505; text-align: center; font-size: 10px; color: #444; border-top: 1px solid #1a1a1a; }
            .player-footer strong { color: #3498db; }
            .player-footer a { color: #666; text-decoration: none; }
        </style>
    </head>
    <body>
    
    <div class="elegant-player sticky-player">
        <div class="player-header">
            <div class="album-art">
                <img id="current-thumb" src="https://semaramedia.web.id/wp-content/uploads/2026/03/pujashanti-high-resolution-logo-1-2.webp" alt="Cover" />
            </div>
            <div class="now-playing-info">
                <span class="status-badge">NOW PLAYING</span>
                <h5 id="current-title">Memuat...</h5>
                <p id="current-artist">Artis</p>
            </div>
        </div>
    
        <div class="custom-controls">
            <div id="progress-container" class="progress-container">
                <div id="progress-bar" class="progress-bar"></div>
            </div>
            <div class="time-info">
                <span id="curr-time">0:00</span>
                <span id="dur-time">0:00</span>
            </div>
    
            <div class="main-btns">
                <button id="prev-btn" title="Lagu Sebelumnya"><i class="fas fa-step-backward"></i></button>
                <button id="play-btn" title="Play/Pause"><i class="fas fa-play"></i></button>
                <button id="next-btn" title="Lagu Selanjutnya"><i class="fas fa-step-forward"></i></button>
            </div>
    
            <div class="volume-control-group">
                <button id="mute-btn" type="button"><i class="fas fa-volume-up"></i></button> 
                <input id="volume-slider" max="1" min="0" step="0.1" type="range" value="1" />
            </div>
        </div>
    
        <audio id="wp-main-audio"></audio>
    
        <ul id="wp-playlist-dynamic" class="playlist-container">
            </ul>
    
        <div class="player-footer">
            <strong>PUJASHANTI Player</strong> kode sumber: 
            <a href="https://gemini.google.com/" target="_blank" rel="noopener">
                <i class="fa-solid fa-robot"></i> Gemini AI
            </a>
        </div>
    </div>
    
    <script src="/js/playlist-data.js?v.2.1"></script>
    <script src="/js/player-logic.js"></script>
    
    </body>

    Kesimpulan

    Dengan memisahkan antara Data (lagu), Logika (JS), dan Tampilan (HTML/CSS), website Anda akan tetap ringan dan mudah dikelola. Anda cukup mengedit file playlist-data.js untuk memperbarui daftar lagu tanpa perlu mengutak-atik halaman WordPress lagi.


    LIHAT JUGA; Mengenal Google Gemini AI: Masa Depan Kecerdasan Buatan