fix: category translate
fix: wrong src of the back button feat: retranslate all
This commit is contained in:
@@ -33,10 +33,14 @@ Changing source text produces a new fingerprint and therefore schedules a new tr
|
||||
|
||||
Only the listed SEO meta fields are sent for translation. Arbitrary metadata, serialized data, credentials, and code are excluded.
|
||||
|
||||
Category and tag names are translated when they are created, edited, or included in a full retranslation. On a translated site, term objects used by archives, navigation, and post metadata use the persisted translated name and description.
|
||||
|
||||
## Routing
|
||||
|
||||
The **Subdirectory** mode resolves configured language paths such as `/en/example-post/`. The **Domain binding** mode maps a request host to a language using one `domain=language` entry per line in Settings. Use one canonical strategy for each language to avoid duplicate URLs. In domain mode, the plugin does not register front-end rewrite rules, so the primary site URL is not affected.
|
||||
|
||||
Post, page, term, and home links are generated for the active language. For example, a theme's "back to home" link that uses `home_url()` resolves to the bound language domain or language subdirectory.
|
||||
|
||||
For a bound subdomain, enter a value such as `en.example.com=en`. The server and DNS must route that hostname to the same WordPress installation before WordPress can resolve the language.
|
||||
|
||||
After changing routing settings, rewrite rules are refreshed. The initial implementation does not yet generate translated permalinks, canonical URLs, `hreflang` alternates, redirects, or sitemap entries.
|
||||
@@ -65,6 +69,10 @@ find . -path './.git' -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 php
|
||||
|
||||
Before production use, add WordPress PHPUnit integration tests with mocked `wp_remote_post` responses. Required coverage includes language resolution, rewrite behavior, persistence reuse and invalidation, Baidu request signing and errors, content filtering, and fallback rendering.
|
||||
|
||||
## Retranslation
|
||||
|
||||
The Posts and Pages lists show a status column for every target language, including the latest successful translation time and a translation action. The Settings page also provides **重新翻译所有内容**. It shows a confirmation warning before scheduling a forced refresh of published posts, pages, categories, and tags; this bypasses persisted translations and consumes Baidu API quota.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- The settings UI accepts language codes but does not yet validate them against a maintained Baidu language-code list.
|
||||
|
||||
@@ -12,6 +12,7 @@ class WPT_Admin {
|
||||
add_filter( 'manage_page_posts_columns', array( $this, 'add_translation_column' ) );
|
||||
add_action( 'manage_post_posts_custom_column', array( $this, 'render_translation_column' ), 10, 2 );
|
||||
add_action( 'manage_page_posts_custom_column', array( $this, 'render_translation_column' ), 10, 2 );
|
||||
add_filter( 'plugin_action_links_' . plugin_basename( WPT_FILE ), array( $this, 'add_plugin_settings_link' ) );
|
||||
}
|
||||
|
||||
public function add_settings_page() {
|
||||
@@ -68,12 +69,12 @@ class WPT_Admin {
|
||||
<?php submit_button(); ?>
|
||||
</form>
|
||||
<hr />
|
||||
<h2>翻译已有内容</h2>
|
||||
<p>保存语言或百度凭据后,使用此操作将所有已发布的文章和页面加入翻译队列。</p>
|
||||
<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
|
||||
<h2>重新翻译所有内容</h2>
|
||||
<p>此操作会将所有已发布文章、页面、分类和标签重新加入翻译队列。</p>
|
||||
<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post" onsubmit="return window.confirm('这将重新翻译所有内容,请注意 API 消耗。确认继续吗?');">
|
||||
<input type="hidden" name="action" value="wpt_queue_existing_translations" />
|
||||
<?php wp_nonce_field( 'wpt_queue_existing_translations' ); ?>
|
||||
<?php submit_button( '翻译已有文章和页面', 'secondary', 'submit', false ); ?>
|
||||
<?php submit_button( '重新翻译所有内容', 'secondary', 'submit', false ); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
@@ -98,17 +99,41 @@ class WPT_Admin {
|
||||
|
||||
foreach ( $post_ids as $post_id ) {
|
||||
foreach ( WPT_Settings::target_languages() as $target_language ) {
|
||||
if ( ! wp_next_scheduled( 'wpt_process_translation', array( $post_id, $target_language ) ) ) {
|
||||
wp_schedule_single_event( time() + 30, 'wpt_process_translation', array( $post_id, $target_language ) );
|
||||
if ( ! wp_next_scheduled( 'wpt_process_translation', array( $post_id, $target_language, true ) ) ) {
|
||||
wp_schedule_single_event( time() + 30, 'wpt_process_translation', array( $post_id, $target_language, true ) );
|
||||
++$scheduled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$terms = get_terms(
|
||||
array(
|
||||
'taxonomy' => array( 'category', 'post_tag' ),
|
||||
'hide_empty' => false,
|
||||
'fields' => 'ids',
|
||||
)
|
||||
);
|
||||
if ( ! is_wp_error( $terms ) ) {
|
||||
foreach ( $terms as $term_id ) {
|
||||
foreach ( WPT_Settings::target_languages() as $target_language ) {
|
||||
if ( ! wp_next_scheduled( 'wpt_process_term_translation', array( $term_id, $target_language, true ) ) ) {
|
||||
wp_schedule_single_event( time() + 30, 'wpt_process_term_translation', array( $term_id, $target_language, true ) );
|
||||
++$scheduled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_safe_redirect( add_query_arg( 'wpt_queued', $scheduled, admin_url( 'options-general.php?page=wp-translate' ) ) );
|
||||
exit;
|
||||
}
|
||||
|
||||
public function add_plugin_settings_link( $links ) {
|
||||
array_unshift( $links, '<a href="' . esc_url( admin_url( 'options-general.php?page=wp-translate' ) ) . '">设置</a>' );
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
public function add_translation_column( $columns ) {
|
||||
$columns['wpt_translation'] = '翻译状态';
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ class WPT_Content_Controller {
|
||||
public function register() {
|
||||
add_action( 'save_post', array( $this, 'schedule_post_translation' ), 20, 3 );
|
||||
add_action( 'wpt_process_translation', array( $this, 'translate_post' ), 10, 3 );
|
||||
add_action( 'wpt_process_term_translation', array( $this, 'translate_term' ), 10, 3 );
|
||||
add_action( 'created_term', array( $this, 'schedule_term_translation' ), 20, 3 );
|
||||
add_action( 'edited_term', array( $this, 'schedule_term_translation' ), 20, 3 );
|
||||
add_filter( 'the_title', array( $this, 'translate_title' ), 20, 2 );
|
||||
add_filter( 'the_content', array( $this, 'translate_content' ), 20 );
|
||||
add_filter( 'get_the_excerpt', array( $this, 'translate_excerpt' ), 20, 2 );
|
||||
@@ -28,6 +31,7 @@ class WPT_Content_Controller {
|
||||
add_filter( 'page_link', array( $this, 'localize_permalink' ), 20 );
|
||||
add_filter( 'post_type_link', array( $this, 'localize_permalink' ), 20 );
|
||||
add_filter( 'term_link', array( $this, 'localize_permalink' ), 20 );
|
||||
add_filter( 'get_term', array( $this, 'translate_term_object' ), 20, 3 );
|
||||
}
|
||||
|
||||
public function schedule_post_translation( $post_id, $post, $update ) {
|
||||
@@ -84,6 +88,39 @@ class WPT_Content_Controller {
|
||||
$this->translate_terms( $post_id, $service, $settings, $target_language, $force_refresh );
|
||||
}
|
||||
|
||||
public function schedule_term_translation( $term_id, $term_taxonomy_id, $taxonomy ) {
|
||||
if ( ! in_array( $taxonomy, array( 'category', 'post_tag' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( WPT_Settings::target_languages() as $target_language ) {
|
||||
if ( ! wp_next_scheduled( 'wpt_process_term_translation', array( $term_id, $target_language, false ) ) ) {
|
||||
wp_schedule_single_event( time() + 30, 'wpt_process_term_translation', array( $term_id, $target_language, false ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function translate_term( $term_id, $target_language, $force_refresh = false ) {
|
||||
$term = get_term( $term_id );
|
||||
$settings = WPT_Settings::get();
|
||||
|
||||
if ( ! $term || is_wp_error( $term ) || ! in_array( $term->taxonomy, array( 'category', 'post_tag' ), true ) || ! WPT_Settings::is_supported_language( $target_language ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$service = new WPT_Translation_Service(
|
||||
$this->store,
|
||||
new WPT_Baidu_Provider( $settings['baidu_app_id'], $settings['baidu_secret_key'] )
|
||||
);
|
||||
|
||||
if ( '' !== $term->name ) {
|
||||
$service->get_or_translate( $term->name, $settings['source_language'], $target_language, 'term:' . $term->term_id . ':name', $force_refresh );
|
||||
}
|
||||
if ( '' !== $term->description ) {
|
||||
$service->get_or_translate( $term->description, $settings['source_language'], $target_language, 'term:' . $term->term_id . ':description', $force_refresh );
|
||||
}
|
||||
}
|
||||
|
||||
public function translate_title( $title, $post_id ) {
|
||||
return $this->translated_value( $title, 'post:' . $post_id . ':post_title' );
|
||||
}
|
||||
@@ -114,6 +151,18 @@ class WPT_Content_Controller {
|
||||
return $this->translated_value( $description, 'term:' . $term_id . ':description' );
|
||||
}
|
||||
|
||||
public function translate_term_object( $term, $taxonomy, $context = '' ) {
|
||||
if ( ! $term instanceof WP_Term || ! in_array( $term->taxonomy, array( 'category', 'post_tag' ), true ) ) {
|
||||
return $term;
|
||||
}
|
||||
|
||||
$translated_term = clone $term;
|
||||
$translated_term->name = $this->translated_value( $term->name, 'term:' . $term->term_id . ':name' );
|
||||
$translated_term->description = $this->translated_value( $term->description, 'term:' . $term->term_id . ':description' );
|
||||
|
||||
return $translated_term;
|
||||
}
|
||||
|
||||
public function translate_seo_value( $value ) {
|
||||
$post_id = get_queried_object_id();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ class WPT_Language_Router {
|
||||
public function register() {
|
||||
add_filter( 'query_vars', array( $this, 'query_vars' ) );
|
||||
add_action( 'parse_request', array( $this, 'resolve_domain_language' ) );
|
||||
add_filter( 'home_url', array( $this, 'localize_home_url' ), 20, 4 );
|
||||
$this->register_rewrite_rules();
|
||||
}
|
||||
|
||||
@@ -81,10 +82,17 @@ class WPT_Language_Router {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$scheme = isset( $parts['scheme'] ) ? $parts['scheme'] . '://' : '//';
|
||||
$host = isset( $parts['host'] ) ? $parts['host'] : '';
|
||||
$port = isset( $parts['port'] ) ? ':' . $parts['port'] : '';
|
||||
$path = '/' . $language . '/' . ltrim( $parts['path'], '/' );
|
||||
$query = isset( $parts['query'] ) ? '?' . $parts['query'] : '';
|
||||
$fragment = isset( $parts['fragment'] ) ? '#' . $parts['fragment'] : '';
|
||||
|
||||
return home_url( $path ) . $query . $fragment;
|
||||
return $scheme . $host . $port . $path . $query . $fragment;
|
||||
}
|
||||
|
||||
public function localize_home_url( $url, $path, $scheme, $blog_id ) {
|
||||
return $this->localized_url( $url );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user