NockedPress

The Code junkyard => Wordpress code => Topic started by: mkmcst on Jul 30, 2026, 10:34 PM

Title: Dynamic Auto-Tagging: Extracts top 6 keywords from post content
Post by: mkmcst on Jul 30, 2026, 10:34 PM
//--------Dynamic Auto-Tagging: Extracts top 6 keywords from post content------------------------------------------
add_action('save_post_post', 'plimoth_dynamic_auto_tags', 20, 3);

function plimoth_dynamic_auto_tags($post_id, $post, $update) {
    if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) return;

    // Combine title and content, strip HTML tags
    $text = strip_tags($post->post_title . ' ' . $post->post_content);

    // Early exit if empty
    if (trim($text) === '') return;

    // List of stop words to ignore
    $stop_words = [
        'the', 'and', 'with', 'from', 'that', 'this', 'have', 'after',
        'will', 'also', 'they', 'your', 'their', 'about', 'which', 'such',
        'some', 'other', 'than', 'then', 'them', 'these', 'those', 'may',
        'might', 'been', 'being', 'over', 'under', 'above', 'below', 'during',
        'before', 'because', 'where', 'when', 'while', 'who', 'whom', 'whose',
        'how', 'why', 'what', 'can', 'could', 'should', 'would', 'shall'
    ];

    // Convert to lowercase safely using multibyte support
    $text = mb_strtolower($text, 'UTF-8');

    // Replace non-word characters with spaces, keeping letters, numbers, and diacritics intact
    // Using Unicode property escapes (\p{L} for letters, \p{N} for numbers)
    $text = preg_replace('/[^\p{L}\p{N}]+/u', ' ', $text);

    // Split into words by whitespace
    $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY);

    // Filter out short words (less than 4 characters) and stop words
    $filtered = [];
    foreach ($words as $word) {
        // Use mb_strlen to accurately count characters in words like "Plymouth"
        if (mb_strlen($word, 'UTF-8') >= 4 && !in_array($word, $stop_words, true)) {
            $filtered[] = $word;
        }
    }

    // Count word frequencies
    $counts = array_count_values($filtered);
    arsort($counts);

    // Get top 6 keywords
    $top_six = array_slice(array_keys($counts), 0, 6);

    // Set tags if available
    if (!empty($top_six)) {
        wp_set_post_tags($post_id, $top_six, true);
    }
}