给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的朋友。