{"id":369,"date":"2026-07-20T09:05:09","date_gmt":"2026-07-20T09:05:09","guid":{"rendered":"https:\/\/tools.dwiyanti.com\/blog\/?p=369"},"modified":"2026-07-20T09:12:42","modified_gmt":"2026-07-20T09:12:42","slug":"keyword-dalam-schema","status":"publish","type":"post","link":"https:\/\/tools.dwiyanti.com\/blog\/keyword-dalam-schema","title":{"rendered":"Keyword dalam Schema"},"content":{"rendered":"<pre style=\"white-space:pre-wrap;\">\nKEYWORD INI DENGAN KONDISI JIKA, JIKA MANUAL TIDK ADA - MAKA CARI TAGS, JIKA MANUAL DAN TAGS TIDAK ADA - MAKA CARI KATEGORI\n---\n\/\/ SCHEMA BLOGPOSTING\nfunction add_blogposting1_schema() {\n     if (!is_single()) {\n        return;\n     }\n\n    global $post;\n\n    \/\/ ========== DATA DASAR ==========\n    $title = get_the_title($post);\n    $url = get_permalink($post);\n    $published = get_the_date('c', $post);\n    $modified = get_the_modified_date('c', $post);\n    $description = get_optimized_meta_description();\n    $site_icon = get_site_icon_url();\n    $site_url    = home_url();\n    $in_language = 'id-ID';\n\n    \/\/ Word count \u2014 untuk AI dan Google menilai content depth\n    $content_raw = get_post_field( 'post_content', $post->ID );\n    $word_count  = str_word_count( wp_strip_all_tags( $content_raw ) );\n\n    \/\/ ========== AMBIL SEMUA GAMBAR (UNIVERSAL) ==========\n    $images = [];\n\n    \/\/ 1. Featured Image (dengan width\/height real)\n    if (has_post_thumbnail($post->ID)) {\n        $image_id = get_post_thumbnail_id($post->ID);\n        $image_url = wp_get_attachment_image_url($image_id, 'full');\n        $image_meta = wp_get_attachment_metadata($image_id);\n        $image_alt  = get_post_meta( $image_id, '_wp_attachment_image_alt', true );\n        $image_cap  = wp_get_attachment_caption( $image_id );\n\n        $images[] = [\n            \"@type\" => \"ImageObject\",\n            \"url\" => $image_url,\n            \"width\" => isset($image_meta['width']) ? $image_meta['width'] : 1200,\n            \"height\" => isset($image_meta['height']) ? $image_meta['height'] : 630\n        ];\n    }\n\n    \/\/ 2. Ambil SEMUA gambar dari konten (tanpa batas 3)\n    $content = get_post_field('post_content', $post->ID);\n    preg_match_all('\/<img[^>]+src=[\"\\']([^\"\\']+)[\"\\']\/i', $content, $matches);\n\n    if (!empty($matches[1])) {\n        foreach ($matches[1] as $img_url) {\n            \/\/ Hindari duplikat dengan featured image\n            $is_duplicate = false;\n            foreach ($images as $img) {\n                if ($img['url'] === $img_url) {\n                    $is_duplicate = true;\n                    break;\n                }\n            }\n\n            if (!$is_duplicate) {\n                $images[] = [\n                    \"@type\" => \"ImageObject\",\n                    \"url\" => $img_url,\n                    \"width\" => 1200,\n                    \"height\" => 630\n                ];\n            }\n        }\n    }\n\n    \/\/ 3. Fallback jika tidak ada gambar sama sekali\n    if (empty($images)) {\n        $images[] = [\n            \"@type\" => \"ImageObject\",\n            \"url\" => \"https:\/\/dwiyanti.com\/wp-content\/themes\/lifestyle\/assets\/images\/DwiYanti.jpeg\",\n            \"width\" => 1200,\n            \"height\" => 630\n        ];\n    }\n\n    \/\/ ========== DETEKSI KATEGORI UNTUK ABOUT ==========\n    $article_type = 'Article';\n    $primary_category = '';\n    $categories = get_the_category();\n    if (!empty($categories)) {\n        $primary_category = $categories[0]->name;\n        $cat_lower = strtolower($primary_category);\n\n        if (in_array($cat_lower, ['beauty', 'skincare', 'makeup'])) {\n            $article_type = 'BeautyTips';\n        } elseif (in_array($cat_lower, ['health', 'wellness', 'fitness'])) {\n            $article_type = 'HealthTopic';\n        } elseif (in_array($cat_lower, ['lifestyle', 'travel', 'fashion'])) {\n            $article_type = 'LifestyleArticle';\n        }\n    }\n\n    \/\/ Keyword dengan tambahan dari ID atribut HTML\n    function get_schema_keywords($post_id) {\n\n        $keywords = [];\n\n        \/\/ 1. Prioritaskan tag\n        $tags = wp_get_post_tags($post_id);\n        foreach ($tags as $tag) {\n            $keywords[] = $tag->name;\n        }\n\n        \/\/ 2. Jika tidak ada tag, gunakan kategori\n        if (empty($keywords)) {\n            $categories = get_the_category($post_id);\n            foreach ($categories as $category) {\n                $keywords[] = $category->name;\n            }\n        }\n\n        \/\/ 3. Ambil ID dari konten post\n        $content = get_post_field('post_content', $post_id);\n        $id_keywords = extract_ids_from_content($content);\n\n        \/\/ Gabungkan dengan keywords yang sudah ada\n        if (!empty($id_keywords)) {\n            $keywords = array_merge($keywords, $id_keywords);\n        }\n\n        return implode(', ', array_unique($keywords));\n    }\n\n    \/\/ Fungsi bantuan untuk mengekstrak ID dari HTML\n    function extract_ids_from_content($content) {\n        $ids = [];\n\n        \/\/ Pattern untuk mencari semua atribut id\n        preg_match_all('\/\\bid=[\"\\']([^\"\\']*)[\"\\']\/', $content, $matches);\n\n        if (!empty($matches[1])) {\n            foreach ($matches[1] as $id) {\n                \/\/ Bersihkan ID (hilangkan spasi, karakter aneh)\n                $clean_id = trim($id);\n                if (!empty($clean_id)) {\n                    $ids[] = $clean_id;\n                }\n            }\n        }\n\n        return $ids;\n    }\n    \/\/END keywords\n\n    \/\/ Mention\n    function get_mentions($post_id) {\n\n        $mentions = [];\n\n        $tags = wp_get_post_tags($post_id);\n\n        foreach ($tags as $tag) {\n\n            $mentions[] = [\n                \"@type\" => \"Thing\",\n                \"name\" => $tag->name\n            ];\n\n        }\n\n        return $mentions;\n    }\n    \/\/ About\n    function get_about_topic($post_id) {\n\n        $categories = get_the_category($post_id);\n\n        if (!empty($categories)) {\n            return $categories[0]->name;\n        }\n\n        return \"Article\";\n    }\n\n\n    \/\/ ========== BANGUN SCHEMA ==========\n    $schema_blog = [\n        \"@context\" => \"https:\/\/schema.org\",\n        \"@graph\" => [\n            [\n                \"@type\" => \"BlogPosting\",\n                '@id' => $url . '#article',\n                'url' => $url,\n                \"headline\" => $title,\n                'name' => $title,\n                \"description\" => $description,\n                'inLanguage' => $in_language,\n                'wordCount' => $word_count,\n                \"keywords\" => get_schema_keywords($post->ID),\n                \"mainEntityOfPage\" => [\n                    \"@type\" => \"WebPage\",\n                    '@id' => $url . '#webpage',\n                ],\n                'isPartOf' => [\n                    '@type' => 'WebSite',\n                    '@id' => $site_url . '\/#website',\n                ],\n                \"author\" => [\n                    \"@type\" => \"Person\",\n                    \"name\" => \"Dwi Yanti\",\n                    \"@id\" => \"https:\/\/me.dwiyanti.com\/#dwi-yanti\",\n                    \"url\" => \"https:\/\/me.dwiyanti.com\"\n                ],\n                \"publisher\" => [\n                    \"@type\" => \"Organization\",\n                    \"@id\" => \"https:\/\/dwiyanti.com\/#organization\",\n                    \"name\" => \"Dwi Yanti SEO\",\n                    \"alternateName\" => \"Dwi Yanti SEO Specialist and Technical SEO Strategist\",\n                    \"logo\" => [\n                        \"@type\" => \"ImageObject\",\n                        \"url\" => $site_icon\n                    ]\n                ],\n                \"datePublished\" => $published,\n                \"dateModified\" => $modified,\n                \"image\" => $images,\n\n                \/\/ articleSection \u2014 bantu Google klaster konten per topik\n                'articleSection' => $article_type,\n\n                \/\/ Speakable \u2014 bantu AI Overview & Google SGE pilih konten utama\n                'speakable' => [\n                    '@type'       => 'SpeakableSpecification',\n                    'cssSelector' => [\n                        'h1',\n                        '.post-content p:first-of-type',   \/\/ Paragraf 1\n                        \".speakable-second\",\n                        \".speakable-last\"\n                    ]\n                ],\n\n                \/\/ ========== GEO OPTIMIZATION ==========\n                \"about\" => [\n                    \"@type\" => \"Thing\",\n                     \"@id\" => home_url('\/#seo'),\n                    \"name\" => get_about_topic($post->ID)\n                ],\n                \"mentions\" => get_mentions($post->ID),\n                \"text\" => wp_trim_words(\n                    wp_strip_all_tags($post->post_content),\n                    700,\n                    '...'\n                ),\n                \"potentialAction\" => [\n                    \"@type\"=>\"ReadAction\",\n                    \"target\"=>$url\n                ]\n            ]\n        ]\n    ];\n\n    \/\/ Tambahkan 'about' untuk kategori Health\n    if ($article_type === 'HealthTopic' && !empty($primary_category)) {\n        $schema[\"@graph\"][0]['about'] = [\n            '@type' => 'MedicalCondition',\n            'name' => $primary_category\n        ];\n    }\n\n    \/\/ ========== OUTPUT ==========\n    echo '<script type=\"application\/ld+json\">' . \"\\n\";\n    echo wp_json_encode($schema_blog, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);\n    echo \"\\n\" . '<\/script>' . \"\\n\";\n}\nadd_action('wp_head', 'add_blogposting1_schema');\n\/\/ END Schema BlogPosting Markup\n\n\ud83c\udfaf Menurut saya, KONFIGURASI TERBAIK adalah:\nKeyword di Schema = MANUAL (bebas dari tags & kategori)\nTags & Kategori = TETAP ADA di tempatnya masing-masing\n\n\ud83d\udcca ALASAN:\nAspek\tPenjelasan\nKeywords Manual\tAnda kontrol penuh. Bisa target kata kunci spesifik yang sudah riset.\nAbout (Kategori)\tMemberi sinyal topik utama ke Google. Ini penting untuk semantic SEO.\nMentions (Tags)\tMenambah konteks dan variasi topik. Bantu Google pahami hubungan antar konten.\n\ud83d\udca1 KENAPA STRATEGI INI TERBAIK?\nTidak ada duplikasi - Keywords beda dengan tags\/kategori\n\nTidak ada keyword stuffing - Masing-masing punya fungsi sendiri\n\nLebih terstruktur - Google dapat memetakan konten dengan lebih baik\n\nFlexibel - Anda bisa custom keywords tanpa merusak struktur\n\n\u26a0\ufe0f YANG PERLU DIHINDARI:\n\u274c Jangan masukkan tags\/kategori ke field \"keywords\"\n\u274c Jangan biarkan keywords kosong\n\u274c Jangan memasukkan keywords yang tidak relevan\n\n\u2705 KESIMPULAN SAYA:\nSetuju! Konfigurasi yang Anda maksud (keyword manual, tags di mentions, kategori di about) adalah STRATEGI TERBAIK.\n\nIni yang saya rekomendasikan sebagai SEO Strategist:\n\ntext\n\u2705 keywords = manual input (target kata kunci utama)\n\u2705 about = kategori (topik utama)\n\u2705 mentions = tags (variasi topik terkait)\nJadi jawaban saya: Sangat baik! Ini pendekatan yang tepat secara SEO. Anda sudah di jalur yang benar! \ud83d\ude80\n\nKALAU MAU DI GABUNGKAN MANUAL + TAGS + KATEGORI\n----\nfunction get_schema_keywords($post_id) {\n    $keywords = [];\n    \n    \/\/ 1. PRIORITAS: Manual (harus diisi)\n    $manual = get_post_meta($post_id, '_schema_keywords_manual', true);\n    if (!empty($manual)) {\n        $keywords[] = $manual;\n    }\n    \n    \/\/ 2. KEDUA: Tags (untuk variasi)\n    $tags = wp_get_post_tags($post_id);\n    foreach ($tags as $tag) {\n        $keywords[] = $tag->name;\n    }\n    \n    \/\/ 3. KETIGA: Kategori (untuk konteks)\n    $categories = get_the_category($post_id);\n    foreach ($categories as $category) {\n        $keywords[] = $category->name;\n    }\n    \n    \/\/ Gabungkan unik\n    return implode(', ', array_unique($keywords));\n}\n\n<\/pre>","protected":false},"excerpt":{"rendered":"KEYWORD INI DENGAN KONDISI JIKA, JIKA MANUAL TIDK ADA &#8211; MAKA CARI TAGS, JIKA MANUAL DAN TAGS TIDAK ADA &#8211; MAKA CARI KATEGORI &#8212; \/\/ SCHEMA BLOGPOSTING function add_blogposting1_schema() { if (!is_single()) { return; } global $post; \/\/ ========== DATA DASAR ========== $title = get_the_title($post); $url = get_permalink($post); $published = get_the_date(&#8216;c&#8217;, $post); $modified = get_the_modified_date(&#8216;c&#8217;, [&hellip;]","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-369","post","type-post","status-publish","format-standard","hentry","category-schema"],"_links":{"self":[{"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/posts\/369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/comments?post=369"}],"version-history":[{"count":3,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/posts\/369\/revisions"}],"predecessor-version":[{"id":374,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/posts\/369\/revisions\/374"}],"wp:attachment":[{"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/media?parent=369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/categories?post=369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tools.dwiyanti.com\/blog\/wp-json\/wp\/v2\/tags?post=369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}