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

news/2025/3/24 16:21:37/文章来源:https://www.cnblogs.com/shamo89/p/18787546

之前有一个用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 Keyconst 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"; // 设置为 hiddenhiddenButton.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的朋友。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904081.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第五章 影响估算的因素

对软件项目产生影响的因素,可以有多种分类方式。了解这些影响因素有助于提高估算的准确度,并改善对软件项目动态特性的整体理解。 影响到项目工作量、成本和进度的最具决定性的因素毫无疑问是项目的规模。其次是正在开发的软件的类型,紧随其后的是人员因素。开发中使用的编程…

2025.3.25(周二)

4、航空服务查询问题:根据航线,仓位,飞行时间查询航空服务。 假设一个中国的航空公司规定:① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。③ 中国国内的航班的商务仓有食物供应,但是…

2025.3.19(周三)

2、找零钱最佳组合假设商店货品价格(R) 都不大于100元(且为整数),若顾客付款(P)在100元内,现有一个程序能在每位顾客付款后给出找零钱的最佳组合(找给顾客货币张数最少)。假定此商店的货币面值只包括:50元(N50)、10元(N10)、 5元(N5)、1元(N1) 四种。请结合等价类划分法…

如何使用microSD卡模块与Arduino

MicroSD卡模块 ESP32有不同的microSD卡模块兼容。我们使用microSD卡模块,它使用SPI通信协议进行通信。您可以使用带有SPI接口的任何其他microSD卡模块。这个microSD卡模块也与Arduino板等其他微控制器兼容。学习如何使用microSD卡模块与Arduino。您可以使用默认SPI引脚将其连接…

VMware ESXi 8.0U3d macOS Unlocker OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版)

VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版)VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成 Marvell AQC 网卡驱动定制版 (集成驱动版) VMware ESXi 8.0U3d macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe …

2025.3.10(周一)

实验二:UI设计 实验目的 本次实验的目的是让大家熟悉Android开发中的UI设计,包括了解和熟悉常用控件的使用、界面布局和事件处理等内容。 实验要求熟悉和掌握界面控件设计 了解Android界面布局 掌握控件的事件处理实验内容 一、 常用控件 1、 常用控件介绍 (1)基本控…

设计一个简单的圆柱形情绪灯

步骤1:打印零件和闪光WLED 3D打印外壳 下载提供的STL或STEP文件,并将它们加载到您首选的切片软件中。调整设置(填充,层高度,支撑),如果需要,打印每个部分。我使用白色PLA,填充15%,层高0.2mm。对于扩散器,它只是一个固体圆柱体,在花瓶模式下打印它。 一旦打印完成,把…

构建一个Pedro Robot

Pedro 2.0是一个完全开源的项目,旨在为每个人提供可访问和可定制的服务。Pedro Robot是一个完全开源的项目,设计为每个人都可以访问和定制。组装起来很容易,不需要螺丝,不需要胶水,不需要工具!完美的制造商,学生和教育工作者希望探索机器人和编程。 所有文档都可以在Pedr…

一文搞懂MCP协议与Function Call的区别

一、前言 大家好,我是六哥! 今天咱们聊聊编程里两个听起来有点复杂的概念——MCP协议和函数调用(function call),其实用大白话来讲,它们就是两种不同的“沟通方式”,就像咱们人与人之间交流也有不同的方式一样。下面我就用生活中的例子和Python代码,给大家好好讲讲它们…

基于Arduino设计RFID门锁系统

使用基于arduino的RFID锁系统实现无缝,无钥匙进入和增强保护,从而改变您的门安全性。你是否厌倦了每次需要开门时都要找钥匙?不如建一个智能锁系统,你只需刷卡就能开门?在本节中,我们将学习如何使用Arduino构建RFID门锁系统。这是一种既有趣又安全的开门方式。 这个Ardui…

MQ消息持久化解决方案

消息持久化 1. RabbitMQ 发送与消费消息的模型2. 消息丢失的几种情况?生产者发送消息未到达交换机消息到达交换机,没有正确路由到队列MQ 宕机,队列中的消息不见了消费者收到消息,还没消费,消费者宕机3. 如何保证消息不丢失? 3.1 生产者确认机制publisher-confirm消息成功…