给wordpress文章提供在线翻译和朗读的功能

之前有一个用wordpress搭的英文站点,我想给文章每个段落下面加两个“朗读”和“翻译”的按钮,方便英语不好的浏览者快速的了解中文意思和读法。

下面给出实现思路,全部是deepseek给出的代码实现的。

1、在(functions.php)文件末尾加上如下代码

function enqueue_custom_scripts() {
    wp_enqueue_script('custom-scripts', get_template_directory_uri() . '/js/custom-scripts.js', array('jquery'), null, true);
    wp_localize_script('custom-scripts', 'postData', array(
        'postUrl' => get_permalink()
    ));
}
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');

2、新建一个 custom-scripts.js ,代码内容如下,然后将该文件放到当前主题文件夹的js文件夹下。

 说一下,我为什么代码里这么多内容啊,是因为我加了很多条件限制,只有满足这些才会在文章段落下出现“朗读”和“翻译”的按钮。主要其实就是addButtons这个方法。

条件1:文章url里带【xxxxxx】关键词

条件2:文章发布日期晚于【2025-03-22 00:00:00】

条件3:文章段落必须是英文的

document.addEventListener("DOMContentLoaded", () => {
//     console.log('Post URL:', postData.postUrl);
    if(checkUrl(postData.postUrl)) {

    
    const paragraphs = document.querySelectorAll("article p");
    const articleDateElement = document.querySelector("article time"); // 文章发布时间元素
    const targetDate = new Date("2025-03-22 00:00:00"); // 目标时间

    // 获取发布时间(假设发布时间是标准格式,如 "2025-03-22 10:30:00")
    if (articleDateElement) {
        const publishedDate = new Date(articleDateElement.getAttribute("datetime"));
        
        // 判断发布时间和语言
        if (publishedDate > targetDate) {
            paragraphs.forEach(paragraph => {
                if (isEnglish(paragraph.innerText)) {
                    addButtons(paragraph);
                }
            });
        }
    }
    
    // 调用插入隐藏按钮的方法
    addHiddenButton();
    }
});

// 判断是否为英文段落(正则匹配英文字符)
function isEnglish(text) {
    const englishChars = text.match(/[A-Za-z]/g) || [];
    const totalChars = text.replace(/\s/g, '').length;

    // 如果至少 80% 的字符是英文字符
    return englishChars.length > 0 && (englishChars.length / totalChars) > 0.8;
}

// 插入按钮的方法
function addButtons(paragraph) {
    // 防止重复插入
    const nextElement = paragraph.nextElementSibling;
     if (nextElement && nextElement.classList.contains("translate-btn")) {
        return;
     }


    // 创建翻译按钮
    const translateButton = document.createElement("button");
    translateButton.innerText = "翻译";
    translateButton.classList.add("translate-btn");
    translateButton.style.marginRight = "10px";
    translateButton.onclick = () => translateText(paragraph, translateButton);

    // 创建播放按钮
    const playButton = document.createElement("button");
    playButton.innerText = "播放";
    playButton.classList.add("play-btn");
    playButton.onclick = () => playText(paragraph.innerText);

    // 插入按钮
    paragraph.insertAdjacentElement("afterend", translateButton);
    paragraph.insertAdjacentElement("afterend", playButton);
}

// DeepSeek 翻译功能
async function translateText(paragraph, button) {
    if (!paragraph || !button) return;
    
    // 点击后禁用按钮,防止重复触发
    button.disabled = true;
    button.innerText = "翻译中..."; // 显示加载状态
    
    const text = paragraph.innerText;
    const apiKey = ''; // 替换为你的API Key
     const userid = document.getElementById("userid").value;
      // console.info("Translation text:", text);
    try {
        const response = await fetch('https://{{翻译接口,你可以换为你自己的}}?text='+text+'&userid='+userid+'&targetLanguage=zh', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${apiKey}`
            }
        });

        const data = await response.json();
        // console.info("Translation resp:", data);
        const translatedText = data.data.translation;

        // 插入翻译内容
        const translatedParagraph = document.createElement('p');
        translatedParagraph.innerText = translatedText;
        translatedParagraph.style.color = '#555';
        translatedParagraph.style.fontStyle = 'italic';
        paragraph.insertAdjacentElement("afterend", translatedParagraph);
        
        button.innerText = "已翻译"; // 修改按钮文字状态
    } catch (error) {
        console.error("Translation error:", error);
        // alert("翻译失败,请稍后再试!");
        button.innerText = "翻译失败";
        button.disabled = false; // 失败后允许重新点击
    }
}

// 文字转语音功能
function playText(text) {
    const speech = new SpeechSynthesisUtterance(text);
    speech.lang = 'en-US';
    speech.rate = 1.0;
    window.speechSynthesis.speak(speech);
}

// 生成并插入隐藏按钮
function addHiddenButton() {
    const article = document.querySelector("article");
    if (!article) return;

    // 生成随机30位字符串
    const randomValue = Array.from({ length: 30 }, () =>
        Math.random().toString(36).charAt(2)
    ).join("");

    // 创建隐藏按钮
    const hiddenButton = document.createElement("input");
    hiddenButton.type = "hidden"; // 设置为 hidden
    hiddenButton.value = randomValue;
    hiddenButton.classList.add("hidden-btn");
     hiddenButton.id = "userid"; //

    // 插入到 article 里
    article.appendChild(hiddenButton);

    // console.log("Inserted hidden button with value:", randomValue);
}

// 校验url,目前只放行“/xxxxxx/”文章页
function checkUrl(str) {
    const target = '/xxxxxx/';
    
    const index = str.indexOf(target);
//     console.log('index----,', index);
    if (index === -1) {
        return false;
    }
    return index + target.length!== str.length;
}
    

3、在(style.css)里加上button的样式

button {
    background: linear-gradient(to bottom, #cfe2f3 0%, #9fbdd7 100%); /* 蓝色渐变背景 */
    color: #333; /* 文字颜色 */
    border: 2px solid #7f9db9; /* 深色边框 */
    border-radius: 8px; /* 圆角边框 */
    padding: 8px 16px;
    font-size: 16px;
    font-weight: bold;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); /* 按钮阴影 */
    cursor: pointer;
    transition: background 0.3s ease;
}

button:hover {
    background: linear-gradient(to bottom, #b0d0e8 0%, #8aaec7 100%); /* 鼠标悬停时的颜色 */
    border-color: #6b8fa5;
}

4、准备一个翻译的后台接口,可以用deepseek、google这些现成的,不过要收费,我是自己写的翻译接口。

5、效果

 6、后期优化

现在功能还不完善,例如播放按钮在某些手机浏览器上没效果。我还希望播放时读到哪个单词,哪个单词就高亮显示。

7、广告

本人有10多年后端开发经验,前端知识也了解,但谈不上精通,最近裁员失业,寻求江浙沪不加班或加班少的工作,薪资可以略低,另外希望结交intj的朋友。

posted @ 2025-03-23 09:45  夏威夷8080  阅读(53)  评论(0)    收藏  举报