PHP部分
add_action('rest_api_init', function () {
register_rest_route('polylang-api/v1', '/untranslated-terms', [
'methods' => 'GET',
'callback' => function ($request) {
$taxonomy = $request->get_param('taxonomy');
$source_lang = $request->get_param('source_lang');
$target_lang = $request->get_param('target_lang');
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false
]);
$result = [];
foreach ($terms as $term) {
$translations = pll_get_term_translations($term->term_id);
if (!isset($translations[$target_lang])) {
$result[] = [
'term_id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
'description' => $term->description,
'taxonomy' => $taxonomy
];
}
}
return [
'count' => count($result),
'terms' => $result
];
}
]);
});
add_action('rest_api_init', function () {
register_rest_route('polylang-api/v1', '/translate-term', [
'methods' => 'POST',
'callback' => function ($request) {
$source_term_id = $request->get_param('source_term_id');
$target_lang = $request->get_param('target_lang');
$name = $request->get_param('name');
$slug = $request->get_param('slug');
$description = $request->get_param('description');
$taxonomy = $request->get_param('taxonomy');
$new_term = wp_insert_term($name, $taxonomy, [
'slug' => $slug,
'description' => $description
]);
$new_term_id = $new_term['term_id'];
pll_set_term_language($new_term_id, $target_lang);
$translations = pll_get_term_translations($source_term_id);
$translations[$target_lang] = $new_term_id;
pll_save_term_translations($translations);
return [
'success' => true,
'term_id' => $new_term_id
];
}
]);
});
add_action('rest_api_init', function () {
register_rest_route('polylang-api/v1', '/term-translation', [
'methods' => 'GET',
'callback' => function ($request) {
$term_id = $request->get_param('term_id');
return pll_get_term_translations($term_id);
}
]);
});
N8N json
{
"name": "Polylang Taxonomy Auto Translation",
"nodes": [
{
"id": "schedule",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [-1200,300],
"parameters": {
"rule": {
"interval":[{"field":"hours","hoursInterval":6}]
}
}
},
{
"id": "setLang",
"name": "Set Language Config",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-1000,300],
"parameters": {
"jsCode": "return [{json:{source_lang:'zh',target_languages:['de','es','ja'],taxonomies:['category','post_tag']}}];"
}
},
{
"id": "splitTax",
"name": "Split Taxonomies",
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [-800,300],
"parameters": {
"fieldToSplitOut":"taxonomies",
"include":"selectedOtherFields",
"fieldsToInclude":"source_lang,target_languages"
}
},
{
"id": "splitLang",
"name": "Split Target Languages",
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [-600,300],
"parameters": {
"fieldToSplitOut":"target_languages",
"include":"selectedOtherFields",
"fieldsToInclude":"taxonomies,source_lang"
}
},
{
"id": "getTerms",
"name": "Get Untranslated Terms",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [-400,300],
"parameters": {
"url": "https://YOURDOMAIN.com/wp-json/polylang-api/v1/untranslated-terms",
"sendQuery": true,
"queryParameters":{
"parameters":[
{"name":"taxonomy","value":"={{$json.taxonomies}}"},
{"name":"source_lang","value":"={{$json.source_lang}}"},
{"name":"target_lang","value":"={{$json.target_languages}}"}
]
}
}
},
{
"id": "ifTerms",
"name": "Has Terms?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [-200,300],
"parameters":{
"conditions":{
"conditions":[
{
"leftValue":"={{$json.count}}",
"operator":{"type":"number","operation":"gt"},
"rightValue":0
}
]
}
}
},
{
"id": "splitTerms",
"name": "Split Terms",
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [0,300],
"parameters":{
"fieldToSplitOut":"terms"
}
},
{
"id": "prepare",
"name": "Prepare DeepSeek Request",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [200,300],
"parameters":{
"jsCode": "const term=$json;\nconst targetLang=$node['Split Target Languages'].json.target_languages;\nconst sourceLang=$node['Split Target Languages'].json.source_lang;\n\nconst requestBody={\nmodel:'deepseek-chat',\nmessages:[\n{role:'system',content:`Translate the following WordPress taxonomy term from ${sourceLang} to ${targetLang}. Return JSON with name, slug and description.`},\n{role:'user',content:`Name:${term.name}\\nSlug:${term.slug}\\nDescription:${term.description}`}\n],\nresponse_format:{type:'json_object'}\n};\n\nreturn {json:{requestBody,term,targetLang}};"
}
},
{
"id": "deepseek",
"name": "DeepSeek Translate",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [400,300],
"parameters":{
"method":"POST",
"url":"https://api.deepseek.com/v1/chat/completions",
"sendHeaders":true,
"headerParameters":{
"parameters":[{"name":"Content-Type","value":"application/json"}]
},
"sendBody":true,
"specifyBody":"json",
"jsonBody":"={{JSON.stringify($json.requestBody)}}"
}
},
{
"id": "parse",
"name": "Parse Translation",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [600,300],
"parameters":{
"jsCode": "const raw=$json.choices[0].message.content;\nconst translated=JSON.parse(raw);\nconst term=$node['Prepare DeepSeek Request'].json.term;\nconst lang=$node['Prepare DeepSeek Request'].json.targetLang;\n\nreturn {json:{source_term_id:term.term_id,taxonomy:term.taxonomy,target_lang:lang,name:translated.name,slug:translated.slug,description:translated.description}};"
}
},
{
"id": "createTerm",
"name": "Create Translated Term",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [800,300],
"parameters":{
"method":"POST",
"url":"https://YOURDOMAIN.com/wp-json/polylang-api/v1/translate-term",
"sendBody":true,
"specifyBody":"json",
"jsonBody":"={{JSON.stringify($json)}}"
}
},
{
"id": "delay",
"name": "Rate Limit",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [1000,300],
"parameters":{"amount":2}
}
],
"connections":{
"Schedule Trigger":{"main":[[{"node":"Set Language Config","type":"main","index":0}]]},
"Set Language Config":{"main":[[{"node":"Split Taxonomies","type":"main","index":0}]]},
"Split Taxonomies":{"main":[[{"node":"Split Target Languages","type":"main","index":0}]]},
"Split Target Languages":{"main":[[{"node":"Get Untranslated Terms","type":"main","index":0}]]},
"Get Untranslated Terms":{"main":[[{"node":"Has Terms?","type":"main","index":0}]]},
"Has Terms?":{"main":[[{"node":"Split Terms","type":"main","index":0}],[]]},
"Split Terms":{"main":[[{"node":"Prepare DeepSeek Request","type":"main","index":0}]]},
"Prepare DeepSeek Request":{"main":[[{"node":"DeepSeek Translate","type":"main","index":0}]]},
"DeepSeek Translate":{"main":[[{"node":"Parse Translation","type":"main","index":0}]]},
"Parse Translation":{"main":[[{"node":"Create Translated Term","type":"main","index":0}]]},
"Create Translated Term":{"main":[[{"node":"Rate Limit","type":"main","index":0}]]}
}
}