translategemma-27b-it实战教程:Ollama WebUI定制化开发——添加多语种快捷翻译按钮
translategemma-27b-it实战教程:Ollama WebUI定制化开发——添加多语种快捷翻译按钮
你是不是也遇到过这样的场景?在Ollama WebUI里用translategemma-27b-it翻译模型,每次都要手动输入一大段提示词,比如“请将这段中文翻译成英文”,或者“把这张图片里的法文翻译成中文”。虽然模型翻译效果不错,但反复输入同样的指令确实有点麻烦。
今天我就来分享一个实用技巧:如何给Ollama WebUI添加多语种快捷翻译按钮。这个功能实现后,你只需要点击一下按钮,就能自动填充对应的翻译指令,大大提升使用效率。整个过程不需要修改Ollama的核心代码,只需要在前端做一些简单的定制化开发。
1. 理解translategemma-27b-it的工作方式
在开始动手之前,我们先要搞清楚translategemma-27b-it这个模型是怎么工作的。理解了它的输入输出格式,我们才能设计出合适的快捷按钮。
1.1 模型的基本特性
translategemma-27b-it是Google基于Gemma 3系列构建的轻量级翻译模型。它有以下几个特点:
- 支持55种语言:覆盖了全球主要语种,从中文、英文到法语、德语、日语等
- 支持图文翻译:不仅能翻译纯文本,还能识别图片中的文字并进行翻译
- 输入格式灵活:可以接受文本字符串,也可以处理896×896分辨率的图片
- 上下文长度2K:总输入上下文长度为2000个token,适合处理中等长度的翻译任务
1.2 标准使用流程
按照官方文档,使用translategemma-27b-it的标准流程是这样的:
- 在Ollama WebUI中选择translategemma:27b模型
- 在输入框中输入完整的翻译指令
- 如果需要翻译图片,上传图片并等待模型处理
- 获取翻译结果
比如要翻译中文到英文,你需要输入这样的提示词:
你是一名专业的中文(zh-Hans)至英语(en)翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循英语语法、词汇及文化敏感性规范。
仅输出英文译文,无需额外解释或评论。请将以下文本翻译成英文:
[这里放你要翻译的文本]
每次都要输入这么长的指令,确实不够方便。接下来我们就来解决这个问题。
2. 分析Ollama WebUI的界面结构
要添加快捷按钮,首先需要了解Ollama WebUI的界面结构。这样我们才知道在哪里添加按钮,以及如何让按钮与现有的输入框交互。
2.1 界面元素分析
打开Ollama WebUI,我们可以看到几个关键部分:
- 模型选择下拉框:位于页面顶部,用于选择不同的模型
- 对话历史区域:显示之前的对话记录
- 输入框区域:包含文本输入框和发送按钮
- 附加功能区域:可能包含文件上传、设置等按钮
我们的目标是在输入框附近添加一排翻译快捷按钮,让用户能够快速选择翻译方向。
2.2 技术实现思路
实现这个功能有几种思路:
- 浏览器扩展:开发一个Chrome或Firefox扩展,在Ollama WebUI页面上注入自定义按钮
- 用户脚本:使用Tampermonkey等用户脚本管理器,通过JavaScript修改页面
- 修改本地文件:直接修改Ollama WebUI的前端代码(如果部署在本地)
考虑到易用性和普及性,我将重点介绍第二种方法——使用用户脚本。这种方法不需要安装额外的浏览器扩展,只需要一个脚本管理器,而且对用户来说更安全。
3. 创建多语种翻译按钮脚本
现在我们来具体实现这个功能。我将提供一个完整的用户脚本,你可以直接复制使用。
3.1 脚本的基本结构
首先,我们需要创建一个新的用户脚本。如果你使用Tampermonkey,点击“添加新脚本”,然后粘贴以下代码:
// ==UserScript==
// @name Ollama WebUI 翻译快捷按钮
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 为Ollama WebUI添加多语种翻译快捷按钮
// @author YourName
// @match http://localhost:11434/*
// @match https://your-ollama-domain.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 等待页面加载完成
window.addEventListener('load', function() {
// 延迟执行,确保所有元素都已加载
setTimeout(initTranslationButtons, 2000);
});
function initTranslationButtons() {
// 这里将添加按钮创建和事件处理逻辑
}
})();
这个脚本框架做了几件事:
- 定义了脚本的基本信息(名称、版本、描述等)
- 指定了脚本生效的网址(你需要根据实际情况修改@match规则)
- 等待页面完全加载后再执行初始化
- 设置了2秒的延迟,确保Ollama WebUI的所有元素都已就位
3.2 定义翻译语言对
接下来,我们需要定义支持的翻译方向。translategemma-27b-it支持55种语言,但我们不需要全部显示,只需要选择最常用的几种即可。
在initTranslationButtons函数之前,添加以下配置:
// 常用翻译语言对配置
const translationPresets = [
{
id: 'zh2en',
name: '中→英',
sourceLang: '中文(zh-Hans)',
targetLang: '英语(en)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
},
{
id: 'en2zh',
name: '英→中',
sourceLang: '英语(en)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
},
{
id: 'zh2ja',
name: '中→日',
sourceLang: '中文(zh-Hans)',
targetLang: '日语(ja)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
},
{
id: 'ja2zh',
name: '日→中',
sourceLang: '日语(ja)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
},
{
id: 'zh2fr',
name: '中→法',
sourceLang: '中文(zh-Hans)',
targetLang: '法语(fr)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
},
{
id: 'fr2zh',
name: '法→中',
sourceLang: '法语(fr)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的${sourceLang}至${targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循${targetLang}语法、词汇及文化敏感性规范。
仅输出${targetLang}译文,无需额外解释或评论。请将以下文本翻译成${targetLang}:\n\n`
}
];
// 图片翻译的特殊提示词
const imageTranslationPrompt = `你是一名专业的翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循目标语言的语法、词汇及文化敏感性规范。
仅输出译文,无需额外解释或评论。请将图片中的文本翻译成目标语言:`;
这里我定义了6个最常用的翻译方向:中英互译、中日互译、中法互译。你可以根据需要添加更多语言对。
3.3 创建按钮容器和按钮
现在我们来完善initTranslationButtons函数,创建实际的按钮界面:
function initTranslationButtons() {
// 查找输入框容器
const inputContainer = document.querySelector('.input-container, [class*="input"], textarea').closest('div');
if (!inputContainer) {
console.log('未找到输入框容器,等待重试...');
setTimeout(initTranslationButtons, 1000);
return;
}
// 创建按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.id = 'translation-buttons-container';
buttonContainer.style.cssText = `
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
padding: 10px;
background: #f5f5f5;
border-radius: 8px;
border: 1px solid #ddd;
`;
// 添加标题
const title = document.createElement('div');
title.textContent = '快速翻译:';
title.style.cssText = `
width: 100%;
font-weight: bold;
margin-bottom: 8px;
color: #333;
font-size: 14px;
`;
buttonContainer.appendChild(title);
// 创建按钮行容器
const buttonRow = document.createElement('div');
buttonRow.style.cssText = `
display: flex;
flex-wrap: wrap;
gap: 6px;
width: 100%;
`;
// 为每个翻译预设创建按钮
translationPresets.forEach(preset => {
const button = document.createElement('button');
button.textContent = preset.name;
button.dataset.presetId = preset.id;
button.style.cssText = `
padding: 6px 12px;
background: #4a90e2;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
transition: background 0.2s;
`;
// 添加悬停效果
button.addEventListener('mouseenter', () => {
button.style.background = '#357ae8';
});
button.addEventListener('mouseleave', () => {
button.style.background = '#4a90e2';
});
// 添加点击事件
button.addEventListener('click', () => {
applyTranslationPreset(preset);
});
buttonRow.appendChild(button);
});
// 添加图片翻译按钮
const imageButton = document.createElement('button');
imageButton.textContent = '图片翻译';
imageButton.style.cssText = `
padding: 6px 12px;
background: #34a853;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
transition: background 0.2s;
`;
imageButton.addEventListener('mouseenter', () => {
imageButton.style.background = '#2e8b47';
});
imageButton.addEventListener('mouseleave', () => {
imageButton.style.background = '#34a853';
});
imageButton.addEventListener('click', () => {
applyImageTranslation();
});
buttonRow.appendChild(imageButton);
buttonContainer.appendChild(buttonRow);
// 将按钮容器插入到输入框上方
inputContainer.parentNode.insertBefore(buttonContainer, inputContainer);
console.log('翻译快捷按钮已添加');
}
这段代码创建了一个美观的按钮栏,包含所有预设的翻译按钮和一个专门的图片翻译按钮。按钮有悬停效果,点击后会调用相应的处理函数。
3.4 实现按钮功能
现在我们需要实现按钮点击后的具体功能。添加以下函数:
function applyTranslationPreset(preset) {
// 查找文本输入框
const textarea = document.querySelector('textarea');
if (!textarea) {
alert('未找到输入框');
return;
}
// 获取当前输入框的内容
const currentText = textarea.value;
// 检查是否已经包含翻译指令
const hasTranslationInstruction = currentText.includes('翻译员') ||
currentText.includes('translate') ||
currentText.includes('翻译成');
let newText = '';
if (hasTranslationInstruction) {
// 如果已有翻译指令,替换为新的
const lines = currentText.split('\n');
const instructionIndex = lines.findIndex(line =>
line.includes('翻译员') || line.includes('translate')
);
if (instructionIndex !== -1) {
// 保留用户输入的待翻译文本
const userText = lines.slice(instructionIndex + 1).join('\n').trim();
newText = preset.prompt.replace('${sourceLang}', preset.sourceLang)
.replace('${targetLang}', preset.targetLang) +
(userText ? userText + '\n' : '');
} else {
// 如果没有找到明确的指令行,直接替换整个内容
newText = preset.prompt.replace('${sourceLang}', preset.sourceLang)
.replace('${targetLang}', preset.targetLang);
}
} else {
// 如果没有翻译指令,添加新的
if (currentText.trim()) {
// 如果已有文本,将其作为待翻译内容
newText = preset.prompt.replace('${sourceLang}', preset.sourceLang)
.replace('${targetLang}', preset.targetLang) +
currentText + '\n';
} else {
// 如果输入框为空,只添加指令
newText = preset.prompt.replace('${sourceLang}', preset.sourceLang)
.replace('${targetLang}', preset.targetLang);
}
}
// 更新输入框内容
textarea.value = newText;
// 自动聚焦到输入框
textarea.focus();
// 触发输入事件,确保UI更新
textarea.dispatchEvent(new Event('input', { bubbles: true }));
// 显示提示
showNotification(`已应用${preset.name}翻译模板`);
}
function applyImageTranslation() {
const textarea = document.querySelector('textarea');
if (!textarea) {
alert('未找到输入框');
return;
}
// 设置图片翻译提示词
const currentText = textarea.value;
let newText = '';
if (currentText.includes('图片') || currentText.includes('image')) {
// 如果已经是图片翻译,保留用户可能添加的额外说明
const lines = currentText.split('\n');
const instructionEnd = lines.findIndex(line => line.includes('文本翻译'));
if (instructionEnd !== -1) {
const userText = lines.slice(instructionEnd + 1).join('\n').trim();
newText = imageTranslationPrompt + (userText ? '\n\n' + userText : '');
} else {
newText = imageTranslationPrompt;
}
} else {
newText = imageTranslationPrompt;
}
textarea.value = newText;
textarea.focus();
textarea.dispatchEvent(new Event('input', { bubbles: true }));
showNotification('已应用图片翻译模板,请上传需要翻译的图片');
}
function showNotification(message) {
// 创建通知元素
const notification = document.createElement('div');
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4a90e2;
color: white;
padding: 12px 20px;
border-radius: 4px;
z-index: 10000;
font-size: 14px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
animation: slideIn 0.3s ease-out;
`;
// 添加动画样式
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
`;
document.head.appendChild(style);
document.body.appendChild(notification);
// 3秒后自动移除
setTimeout(() => {
notification.style.animation = 'fadeOut 0.3s ease-out';
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 300);
}, 3000);
}
这些函数实现了按钮的核心功能:
applyTranslationPreset:处理文本翻译按钮点击,智能处理输入框内容applyImageTranslation:处理图片翻译按钮点击showNotification:显示操作反馈,提升用户体验
3.5 添加模型检测功能
为了让脚本更加智能,我们还可以添加模型检测功能,只在translategemma模型激活时显示翻译按钮:
// 添加模型检测函数
function checkCurrentModel() {
// 尝试查找模型选择元素
const modelSelect = document.querySelector('select, [class*="model"], [class*="Model"]');
if (modelSelect) {
const currentModel = modelSelect.value || modelSelect.textContent;
// 检查是否是translategemma模型
const isTranslateModel = currentModel.toLowerCase().includes('translategemma') ||
currentModel.toLowerCase().includes('translate');
const buttonContainer = document.getElementById('translation-buttons-container');
if (isTranslateModel) {
// 如果是翻译模型,显示按钮
if (buttonContainer) {
buttonContainer.style.display = 'flex';
} else {
// 如果按钮容器不存在,重新初始化
initTranslationButtons();
}
} else {
// 如果不是翻译模型,隐藏按钮
if (buttonContainer) {
buttonContainer.style.display = 'none';
}
}
}
}
// 修改初始化函数,添加模型变化监听
function initTranslationButtons() {
// ... 之前的代码不变 ...
// 添加模型变化监听
const modelSelect = document.querySelector('select, [class*="model"], [class*="Model"]');
if (modelSelect) {
modelSelect.addEventListener('change', checkCurrentModel);
}
// 初始检查
checkCurrentModel();
// 定期检查(防止动态加载)
setInterval(checkCurrentModel, 3000);
}
4. 完整脚本与使用指南
现在我把完整的脚本代码提供给你,并说明如何使用。
4.1 完整用户脚本代码
// ==UserScript==
// @name Ollama WebUI 翻译快捷按钮
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 为Ollama WebUI添加多语种翻译快捷按钮,支持translategemma-27b-it等翻译模型
// @author CSDN技术博客
// @match http://localhost:11434/*
// @match http://127.0.0.1:11434/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 常用翻译语言对配置
const translationPresets = [
{
id: 'zh2en',
name: '中→英',
sourceLang: '中文(zh-Hans)',
targetLang: '英语(en)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
},
{
id: 'en2zh',
name: '英→中',
sourceLang: '英语(en)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
},
{
id: 'zh2ja',
name: '中→日',
sourceLang: '中文(zh-Hans)',
targetLang: '日语(ja)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
},
{
id: 'ja2zh',
name: '日→中',
sourceLang: '日语(ja)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
},
{
id: 'zh2fr',
name: '中→法',
sourceLang: '中文(zh-Hans)',
targetLang: '法语(fr)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
},
{
id: 'fr2zh',
name: '法→中',
sourceLang: '法语(fr)',
targetLang: '中文(zh-Hans)',
prompt: `你是一名专业的{sourceLang}至{targetLang}翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循{targetLang}语法、词汇及文化敏感性规范。
仅输出{targetLang}译文,无需额外解释或评论。请将以下文本翻译成{targetLang}:\n\n`
}
];
// 图片翻译提示词
const imageTranslationPrompt = `你是一名专业的翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循目标语言的语法、词汇及文化敏感性规范。
仅输出译文,无需额外解释或评论。请将图片中的文本翻译成目标语言:`;
// 等待页面加载
window.addEventListener('load', function() {
setTimeout(initTranslationButtons, 2000);
});
function initTranslationButtons() {
// 查找输入区域
const inputAreas = document.querySelectorAll('textarea');
if (inputAreas.length === 0) {
setTimeout(initTranslationButtons, 1000);
return;
}
const textarea = inputAreas[0];
const inputContainer = textarea.closest('div') || textarea.parentElement;
if (!inputContainer) {
setTimeout(initTranslationButtons, 1000);
return;
}
// 检查是否已添加按钮
if (document.getElementById('translation-buttons-container')) {
return;
}
// 创建按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.id = 'translation-buttons-container';
buttonContainer.style.cssText = `
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
padding: 12px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 10px;
border: none;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
`;
// 添加标题
const title = document.createElement('div');
title.textContent = '🚀 快速翻译';
title.style.cssText = `
width: 100%;
font-weight: bold;
margin-bottom: 10px;
color: white;
font-size: 16px;
text-shadow: 0 1px 2px rgba(0,0,0,0.2);
`;
buttonContainer.appendChild(title);
// 创建按钮行
const buttonRow = document.createElement('div');
buttonRow.style.cssText = `
display: flex;
flex-wrap: wrap;
gap: 8px;
width: 100%;
`;
// 添加翻译按钮
translationPresets.forEach(preset => {
const button = document.createElement('button');
button.textContent = preset.name;
button.dataset.presetId = preset.id;
button.style.cssText = `
padding: 8px 16px;
background: rgba(255,255,255,0.9);
color: #333;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.2s;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
`;
button.addEventListener('mouseenter', () => {
button.style.background = 'white';
button.style.transform = 'translateY(-2px)';
button.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
});
button.addEventListener('mouseleave', () => {
button.style.background = 'rgba(255,255,255,0.9)';
button.style.transform = 'translateY(0)';
button.style.boxShadow = '0 2px 5px rgba(0,0,0,0.1)';
});
button.addEventListener('click', () => {
applyTranslationPreset(preset);
});
buttonRow.appendChild(button);
});
// 添加图片翻译按钮
const imageButton = document.createElement('button');
imageButton.textContent = '🖼️ 图片翻译';
imageButton.style.cssText = `
padding: 8px 16px;
background: rgba(52, 168, 83, 0.9);
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.2s;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
`;
imageButton.addEventListener('mouseenter', () => {
imageButton.style.background = 'rgb(46, 139, 71)';
imageButton.style.transform = 'translateY(-2px)';
imageButton.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
});
imageButton.addEventListener('mouseleave', () => {
imageButton.style.background = 'rgba(52, 168, 83, 0.9)';
imageButton.style.transform = 'translateY(0)';
imageButton.style.boxShadow = '0 2px 5px rgba(0,0,0,0.1)';
});
imageButton.addEventListener('click', applyImageTranslation);
buttonRow.appendChild(imageButton);
buttonContainer.appendChild(buttonRow);
inputContainer.parentNode.insertBefore(buttonContainer, inputContainer);
// 添加模型检测
setupModelDetection();
}
function applyTranslationPreset(preset) {
const textarea = document.querySelector('textarea');
if (!textarea) return;
const currentText = textarea.value;
const prompt = preset.prompt
.replace('{sourceLang}', preset.sourceLang)
.replace('{targetLang}', preset.targetLang);
let newText = '';
if (currentText.includes('翻译员') || currentText.includes('translate')) {
// 替换现有翻译指令
const lines = currentText.split('\n');
const userText = lines.slice(-1)[0].trim() ? lines.slice(-1).join('\n') : '';
newText = prompt + (userText || '');
} else if (currentText.trim()) {
// 添加翻译指令并保留现有文本
newText = prompt + currentText;
} else {
// 只添加翻译指令
newText = prompt;
}
textarea.value = newText;
textarea.focus();
textarea.dispatchEvent(new Event('input', { bubbles: true }));
showNotification(`✅ 已应用 ${preset.name} 翻译模板`);
}
function applyImageTranslation() {
const textarea = document.querySelector('textarea');
if (!textarea) return;
textarea.value = imageTranslationPrompt;
textarea.focus();
textarea.dispatchEvent(new Event('input', { bubbles: true }));
showNotification('🖼️ 已应用图片翻译模板,请上传需要翻译的图片');
}
function showNotification(message) {
const notification = document.createElement('div');
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 12px 24px;
border-radius: 8px;
z-index: 10000;
font-size: 14px;
font-weight: 500;
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
animation: slideIn 0.3s ease-out;
`;
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
`;
document.head.appendChild(style);
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = 'fadeOut 0.3s ease-out';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
function setupModelDetection() {
// 定期检查当前模型
setInterval(() => {
const modelSelect = document.querySelector('select');
if (modelSelect) {
const currentModel = modelSelect.value || modelSelect.textContent;
const buttonContainer = document.getElementById('translation-buttons-container');
if (buttonContainer) {
if (currentModel.toLowerCase().includes('translategemma') ||
currentModel.toLowerCase().includes('translate')) {
buttonContainer.style.display = 'flex';
} else {
buttonContainer.style.display = 'none';
}
}
}
}, 2000);
}
})();
4.2 安装和使用步骤
按照以下步骤安装和使用这个脚本:
-
安装Tampermonkey扩展
- 打开Chrome浏览器(或其他基于Chromium的浏览器)
- 访问Chrome网上应用店
- 搜索"Tampermonkey"并安装
-
创建新脚本
- 点击浏览器右上角的Tampermonkey图标
- 选择"创建新脚本"
- 删除默认代码,粘贴上面提供的完整脚本代码
-
修改匹配规则
- 找到代码中的
@match部分 - 将
http://localhost:11434/*改为你的Ollama WebUI地址 - 如果你的Ollama运行在其他端口或域名,添加相应的匹配规则
- 找到代码中的
-
保存并启用
- 按
Ctrl+S保存脚本 - 确保脚本处于启用状态(Tampermonkey管理面板中开关为绿色)
- 按
-
使用翻译按钮
- 打开Ollama WebUI
- 选择translategemma:27b模型
- 在输入框上方会出现翻译快捷按钮栏
- 点击相应按钮即可快速应用翻译指令
4.3 自定义配置
如果你需要添加更多语言对,可以修改translationPresets数组。每个预设对象包含以下属性:
{
id: '唯一标识', // 如'zh2de'表示中文到德语
name: '显示名称', // 按钮上显示的文字,如'中→德'
sourceLang: '源语言', // 完整的语言名称,如'中文(zh-Hans)'
targetLang: '目标语言', // 完整的语言名称,如'德语(de)'
prompt: '提示词模板' // 翻译指令模板,使用{sourceLang}和{targetLang}作为占位符
}
5. 效果展示与使用技巧
5.1 实际效果展示
安装脚本后,当你打开Ollama WebUI并选择translategemma模型时,会在输入框上方看到一个美观的按钮栏:
点击"中→英"按钮,输入框会自动填充:
你是一名专业的中文(zh-Hans)至英语(en)翻译员。你的目标是准确传达原文的含义与细微差别,同时遵循英语语法、词汇及文化敏感性规范。
仅输出英文译文,无需额外解释或评论。请将以下文本翻译成英文:
你只需要在后面输入要翻译的中文文本即可。
5.2 使用技巧和建议
-
智能替换:如果输入框中已有内容,脚本会智能判断是否需要替换翻译指令,还是保留用户输入的待翻译文本。
-
图片翻译:点击"图片翻译"按钮后,会应用专门的图片翻译指令,然后你可以上传包含文字的图片进行翻译。
-
多语言支持:脚本预设了6种常用翻译方向,你可以根据需要自行添加更多语言对。
-
模型检测:脚本会自动检测当前选择的模型,只在翻译模型激活时显示按钮,避免干扰其他模型的使用。
-
响应式设计:按钮栏采用flex布局,在不同屏幕尺寸下都能良好显示。
5.3 常见问题解决
问题1:按钮没有显示
- 检查Tampermonkey脚本是否启用
- 检查Ollama WebUI地址是否与脚本匹配规则一致
- 刷新页面重新加载
问题2:按钮点击没反应
- 检查浏览器控制台是否有错误信息
- 确保已选择translategemma模型
- 尝试重新安装脚本
问题3:提示词格式不正确
- 检查translategemma模型是否支持你选择的语言对
- 确保语言代码格式正确(如zh-Hans、en、ja等)
6. 总结
通过这个简单的定制化开发,我们成功为Ollama WebUI添加了多语种快捷翻译按钮功能。这个方案有以下几个优点:
- 提升效率:一键填充翻译指令,节省重复输入的时间
- 使用方便:无需修改Ollama源代码,通过用户脚本即可实现
- 灵活配置:可以轻松添加或修改支持的翻译语言对
- 智能适配:自动检测翻译模型,只在需要时显示按钮
- 用户体验好:美观的界面设计,流畅的交互效果
这个方案不仅适用于translategemma-27b-it模型,理论上也适用于其他需要特定提示词的模型。你可以根据类似思路,为其他模型创建专属的快捷功能按钮。
翻译模型的使用体验很大程度上取决于交互的便捷性。通过这样的小优化,能让强大的AI翻译能力更好地服务于实际工作需求。希望这个教程对你有所帮助,如果你有更好的想法或改进建议,欢迎在评论区分享交流。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)