Compare commits

..
15 changed files with 1090 additions and 1072 deletions

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
# Composer dependencies (regenerated with composer install)
/vendor/
# PHPUnit cache
.phpunit.result.cache
# Stray gettext output written by `msgfmt` (without -o) to the CWD.
/messages.mo
# Claude Code config and code graph
/.claude/
/.codegraph/
# OS
.DS_Store
Thumbs.db

View file

@ -1,60 +1,5 @@
== Changelog == == Changelog ==
= 1.2.3 =
_Release date: 2026-08-24_
**Changed**
* Manager (by ROBOTSTXT) detection now checks the ecosystem presence constant `ROBOTSTXT_MANAGER_NOTICED` (defined by Manager 1.6.2+) instead of scanning the installed plugin list on every call. On sites running older Manager versions the detection falls back to the previous plugin-list scan.
**Compatibility**
* WordPress: 7.0 - 7.1
* PHP: 5.6 - 8.5
* WP-CLI: 2.12 or newer
**Tests**
* PHP Coding Standards: WordPress-Core, WordPress-Docs, WordPress-Extra
* PHPCompatibility: 5.6 - 8.5
* PHPStan: level 9 (incl. wp-compat @ Requires at least 7.0)
* PHPUnit: all tests passing (single-site), including both Manager-detection paths (constant defined / not defined)
= 1.2.2 =
_Release date: 2026-08-17_
**Highlights**
* Manager (by ROBOTSTXT) detection: a dismissible notice on the Plugins list screens and a persistent warning on the plugin settings pages recommend installing Manager when it is not active, since plugin updates are delivered through it.
* Removed the bundled JSON updater; updates are now handled by Manager (by ROBOTSTXT).
**Added**
* Dismissible admin notice on the site and network Plugins list screens recommending Manager (by ROBOTSTXT) (`https://www.robotstxt.software/plugins/robotstxt-manager/`) when it is not installed and active.
* Persistent (non-dismissible) warning with the same recommendation on the site and network settings pages of the plugin when Manager is not active.
**Changed**
* Removed the bundled `class-robotstxt-updater.php` library and the `update.json` file. Plugin updates are now delivered through Manager (by ROBOTSTXT).
* Plugin URI and new Update URI header now point to `https://www.robotstxt.software/plugins/robotstxt-ai-translator/`; Author URI now points to `https://www.robotstxt.software/`.
* Minimum PHP version lowered from 7.4 to 5.6, matching the real compatibility floor verified with a PHPCompatibility 5.6-8.5 scan. Minimum WordPress version remains 7.0 (the plugin uses the native WordPress AI client).
* Updated the Spanish (es_ES) and Catalan (ca) translations, including the new Manager notice strings.
**Compatibility**
* WordPress: 7.0 - 7.1
* PHP: 5.6 - 8.5
* WP-CLI: 2.12 or newer
**Tests**
* PHP Coding Standards: WordPress-Core, WordPress-Docs, WordPress-Extra
* PHPCompatibility: 5.6 - 8.5
* PHPStan: level 9 (incl. wp-compat @ Requires at least 7.0)
* PHPUnit: 57/57 tests passing (single-site)
= 1.2.1 = = 1.2.1 =
_Release date: 2026-08-07_ _Release date: 2026-08-07_

476
class-robotstxt-updater.php Normal file
View file

@ -0,0 +1,476 @@
<?php
/**
* Generic JSON-based updater for ROBOTSTXT plugins.
*
* Copy this file into any ROBOTSTXT plugin. It auto-configures itself by
* reading the plugin headers and looking for a `Gitea Plugin URI` header to
* construct the remote update.json URL.
*
* Usage in the main plugin file:
* require_once AI_TRANSLATOR_DIR . 'class-robotstxt-updater.php';
* Robotstxt_Updater::init( AI_TRANSLATOR_FILE );
*
* @package ROBOTSTXT
* @since 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Robotstxt_Updater' ) ) {
/**
* Generic updater that works with any ROBOTSTXT plugin.
*
* Reads the plugin headers to construct the remote update.json URL and
* hooks into WordPress's standard update mechanism.
*
* @since 1.0.0
*/
class Robotstxt_Updater {
/**
* Absolute path to the main plugin file.
*
* @since 1.0.0
* @var string
*/
private $plugin_file_path;
/**
* Plugin basename (e.g. 'my-plugin/my-plugin.php').
*
* @since 1.0.0
* @var string
*/
private $plugin_basename;
/**
* Plugin slug (directory name).
*
* @since 1.0.0
* @var string
*/
private $plugin_slug;
/**
* URL of the remote update.json file.
*
* @since 1.0.0
* @var string
*/
private $json_url;
/**
* Transient cache key for this plugin's remote data.
*
* @since 1.0.0
* @var string
*/
private $cache_key;
/**
* Parsed plugin file headers.
*
* @since 1.0.0
* @var array<string,bool|string>
*/
private $plugin_data;
/**
* Creates the updater instance and registers WordPress hooks.
*
* @since 1.0.0
*
* @param string $plugin_file_path Absolute path to the main plugin file.
*
* @return void
*/
public static function init( $plugin_file_path ) {
$instance = new self( (string) $plugin_file_path );
$instance->register();
}
/**
* Constructor populates instance state from the plugin file headers.
*
* @since 1.0.0
*
* @param string $plugin_file_path Absolute path to the main plugin file.
*/
private function __construct( $plugin_file_path ) {
$this->plugin_file_path = (string) $plugin_file_path;
$this->plugin_basename = plugin_basename( $this->plugin_file_path );
$this->plugin_slug = dirname( $this->plugin_basename );
$this->plugin_data = $this->get_plugin_data();
$this->json_url = $this->build_json_url();
$this->cache_key = 'robotstxt_updater_' . md5( $this->plugin_basename );
}
/**
* Registers the WordPress hooks needed for update checking.
*
* @since 1.0.0
*
* @return void
*/
private function register() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'inject_update_info' ) );
add_filter( 'plugins_api', array( $this, 'provide_plugin_details' ), 10, 3 );
add_action( 'admin_init', array( $this, 'handle_cache_clear' ) );
add_action( 'robotstxt_updater_clear_cache', array( $this, 'clear_cache' ) );
}
/**
* Returns the plugin headers, loading the admin helper file if needed.
*
* @since 1.0.0
*
* @return array<string,bool|string>
*/
private function get_plugin_data() {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$data = get_plugin_data( $this->plugin_file_path, false, false );
return is_array( $data ) ? $data : array();
}
/**
* Builds the remote update.json URL from the plugin headers.
*
* Uses the `Gitea Plugin URI` header when present. Falls back to the
* `Plugin URI` header for legacy configurations. If neither yields a
* usable URL, constructs one from the plugin slug.
*
* @since 1.0.0
*
* @return string Fully-qualified URL.
*/
private function build_json_url() {
$gitea_uri = isset( $this->plugin_data['Gitea Plugin URI'] )
? (string) $this->plugin_data['Gitea Plugin URI']
: '';
if ( '' !== $gitea_uri ) {
// Full URL already provided.
if ( 0 === strpos( $gitea_uri, 'http' ) ) {
return rtrim( $gitea_uri, '/' ) . '/raw/branch/main/update.json';
}
// "OWNER/REPO" short-form.
if ( (bool) preg_match( '#^[^/]+/[^/]+$#', $gitea_uri ) ) {
return 'https://git.robotstxt.es/' . $gitea_uri . '/raw/branch/main/update.json';
}
}
// Fallback: Plugin URI on the Gitea server.
$plugin_uri = isset( $this->plugin_data['PluginURI'] )
? (string) $this->plugin_data['PluginURI']
: '';
if ( '' !== $plugin_uri && false !== strpos( $plugin_uri, 'git.robotstxt.es' ) ) {
return rtrim( $plugin_uri, '/' ) . '/raw/branch/main/update.json';
}
// Last resort: derive from the plugin slug.
return 'https://git.robotstxt.es/ROBOTSTXT/' . $this->plugin_slug . '/raw/branch/main/update.json';
}
/**
* Injects update information into WordPress's plugin update transient.
*
* Hooked to `pre_set_site_transient_update_plugins`.
*
* @since 1.0.0
*
* @param mixed $transient The update_plugins transient value.
*
* @return mixed The (possibly modified) transient.
*/
public function inject_update_info( $transient ) {
if ( ! is_object( $transient ) ) {
return $transient;
}
/**
* Type narrowed to stdClass after is_object() check above.
*
* @var stdClass $transient
*/
if ( empty( $transient->checked ) || ! is_array( $transient->checked ) ) {
return $transient;
}
if ( empty( $transient->checked[ $this->plugin_basename ] ) ) {
return $transient;
}
$checked_value = $transient->checked[ $this->plugin_basename ];
$current_version = is_scalar( $checked_value ) ? (string) $checked_value : '';
$remote = $this->get_remote_data();
if ( ! isset( $remote['version'], $remote['download_url'] ) ) {
return $transient;
}
if ( ! is_string( $remote['version'] ) || ! is_string( $remote['download_url'] ) ) {
return $transient;
}
if ( '' === $remote['download_url'] ) {
return $transient;
}
if ( ! $this->is_compatible( $remote ) ) {
return $transient;
}
if ( version_compare( $remote['version'], $current_version, '>' ) ) {
$slug = isset( $remote['slug'] ) && is_string( $remote['slug'] ) ? $remote['slug'] : $this->plugin_slug;
$homepage = isset( $remote['homepage'] ) && is_string( $remote['homepage'] ) ? $remote['homepage'] : '';
if ( '' === $homepage && isset( $this->plugin_data['PluginURI'] ) ) {
$homepage = (string) $this->plugin_data['PluginURI'];
}
$update = (object) array(
'slug' => $slug,
'plugin' => $this->plugin_basename,
'new_version' => $remote['version'],
'url' => $homepage,
'package' => $remote['download_url'],
'tested' => isset( $remote['tested'] ) && is_string( $remote['tested'] ) ? $remote['tested'] : '',
'requires' => isset( $remote['requires'] ) && is_string( $remote['requires'] ) ? $remote['requires'] : '',
'requires_php' => isset( $remote['requires_php'] ) && is_string( $remote['requires_php'] ) ? $remote['requires_php'] : '',
);
if ( ! isset( $transient->response ) || ! is_array( $transient->response ) ) {
$transient->response = array();
}
$transient->response[ $this->plugin_basename ] = $update;
}
return $transient;
}
/**
* Provides plugin details for the "View details" modal.
*
* Hooked to `plugins_api`.
*
* @since 1.0.0
*
* @param false|object|array<string,mixed> $result The existing result.
* @param string $action The type of information being requested.
* @param object $args Plugin API arguments.
*
* @return false|object|array<string,mixed>
*/
public function provide_plugin_details( $result, $action, $args ) {
if ( 'plugin_information' !== $action ) {
return $result;
}
if ( ! is_object( $args ) || empty( $args->slug ) || $args->slug !== $this->plugin_slug ) {
return $result;
}
$remote = $this->get_remote_data();
if ( empty( $remote['version'] ) ) {
return $result;
}
$name = isset( $remote['name'] ) && is_string( $remote['name'] ) ? $remote['name'] : ( isset( $this->plugin_data['Name'] ) ? (string) $this->plugin_data['Name'] : $this->plugin_slug );
$slug = isset( $remote['slug'] ) && is_string( $remote['slug'] ) ? $remote['slug'] : $this->plugin_slug;
$version = is_string( $remote['version'] ) ? $remote['version'] : '';
$author = isset( $remote['author'] ) && is_string( $remote['author'] ) ? $remote['author'] : ( isset( $this->plugin_data['Author'] ) ? (string) $this->plugin_data['Author'] : '' );
$homepage = isset( $remote['homepage'] ) && is_string( $remote['homepage'] ) ? $remote['homepage'] : ( isset( $this->plugin_data['PluginURI'] ) ? (string) $this->plugin_data['PluginURI'] : '' );
$requires = isset( $remote['requires'] ) && is_string( $remote['requires'] ) ? $remote['requires'] : '';
$tested = isset( $remote['tested'] ) && is_string( $remote['tested'] ) ? $remote['tested'] : '';
$req_php = isset( $remote['requires_php'] ) && is_string( $remote['requires_php'] ) ? $remote['requires_php'] : '';
$description = isset( $remote['description'] ) && is_string( $remote['description'] ) ? $remote['description'] : ( isset( $this->plugin_data['Description'] ) ? (string) $this->plugin_data['Description'] : '' );
$changelog = isset( $remote['changelog'] ) && is_string( $remote['changelog'] ) ? $remote['changelog'] : '';
$download = isset( $remote['download_url'] ) && is_string( $remote['download_url'] ) ? $remote['download_url'] : '';
return (object) array(
'name' => $name,
'slug' => $slug,
'version' => $version,
'author' => $author,
'homepage' => $homepage,
'requires' => $requires,
'tested' => $tested,
'requires_php' => $req_php,
'sections' => array(
'description' => $description,
'changelog' => $changelog,
),
'download_link' => $download,
);
}
/**
* Returns the remote update data, reading from cache or fetching fresh.
*
* The data is stored with an HMAC signature (using AUTH_SALT) to detect
* cache tampering. Falls back to unsigned caching when AUTH_SALT is empty.
*
* @since 1.0.0
*
* @return array<string,mixed>
*/
private function get_remote_data() {
$cached = get_site_transient( $this->cache_key );
// Verify HMAC signature when AUTH_SALT is available.
if ( false !== $cached && defined( 'AUTH_SALT' ) && '' !== AUTH_SALT ) {
if ( is_array( $cached ) && isset( $cached['signature'], $cached['data'] ) && is_string( $cached['signature'] ) ) {
$payload_data = is_array( $cached['data'] ) ? $cached['data'] : array();
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- Used only for HMAC; data is never unserialized.
$expected_sig = hash_hmac( 'sha256', $this->cache_key . serialize( $payload_data ), AUTH_SALT );
if ( hash_equals( $expected_sig, $cached['signature'] ) ) {
return $payload_data;
}
// Signature invalid — delete corrupted cache entry.
delete_site_transient( $this->cache_key );
$cached = false;
}
}
if ( false !== $cached ) {
// Legacy cache format (no HMAC).
return is_array( $cached ) ? $cached : array();
}
$remote = $this->fetch_json();
$data = is_array( $remote ) ? $remote : array();
if ( defined( 'AUTH_SALT' ) && '' !== AUTH_SALT ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- Used only for HMAC; data is never unserialized.
$signature = hash_hmac( 'sha256', $this->cache_key . serialize( $data ), AUTH_SALT );
$payload = array(
'data' => $data,
'timestamp' => time(),
'signature' => $signature,
);
set_site_transient( $this->cache_key, $payload, 6 * HOUR_IN_SECONDS );
} else {
set_site_transient( $this->cache_key, $data, 6 * HOUR_IN_SECONDS );
}
return $data;
}
/**
* Fetches and decodes the remote update.json file.
*
* @since 1.0.0
*
* @return array<string,mixed>
*/
private function fetch_json() {
$response = wp_remote_get(
$this->json_url,
array(
'timeout' => 10,
'headers' => array(
'Accept' => 'application/json',
),
)
);
if ( is_wp_error( $response ) ) {
return array();
}
$code = (int) wp_remote_retrieve_response_code( $response );
if ( $code < 200 || $code >= 300 ) {
return array();
}
$body = wp_remote_retrieve_body( $response );
$data = json_decode( $body, true );
return is_array( $data ) ? $data : array();
}
/**
* Checks whether the remote version is compatible with the current environment.
*
* @since 1.0.0
*
* @param array<string,mixed> $remote Remote update data.
*
* @return bool True if compatible.
*/
private function is_compatible( array $remote ) {
if ( isset( $remote['requires_php'] ) && is_string( $remote['requires_php'] ) && '' !== $remote['requires_php'] ) {
if ( version_compare( PHP_VERSION, $remote['requires_php'], '<' ) ) {
return false;
}
}
if ( isset( $remote['requires'] ) && is_string( $remote['requires'] ) && '' !== $remote['requires'] ) {
if ( version_compare( (string) get_bloginfo( 'version' ), $remote['requires'], '<' ) ) {
return false;
}
}
return true;
}
/**
* Handles a manual cache-clear request triggered via a URL parameter.
*
* Validates nonce and capability before clearing.
*
* @since 1.0.0
*
* @return void
*/
public function handle_cache_clear() {
$clear_cache = filter_input( INPUT_GET, 'robotstxt_clear_update_cache', FILTER_UNSAFE_RAW );
if ( null === $clear_cache ) {
return;
}
$nonce_raw = filter_input( INPUT_GET, '_wpnonce', FILTER_UNSAFE_RAW );
$nonce = is_string( $nonce_raw ) ? sanitize_text_field( wp_unslash( $nonce_raw ) ) : '';
if ( ! wp_verify_nonce( $nonce, 'robotstxt_clear_update_cache' ) ) {
wp_die( esc_html__( 'Security check failed.', 'robotstxt-ai-translator' ) );
}
if ( ! current_user_can( 'update_plugins' ) ) {
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'robotstxt-ai-translator' ) );
}
$this->clear_cache();
wp_safe_redirect( remove_query_arg( array( 'robotstxt_clear_update_cache', '_wpnonce' ) ) );
exit;
}
/**
* Deletes the cached remote data for this plugin.
*
* @since 1.0.0
*
* @return void
*/
public function clear_cache() {
delete_site_transient( $this->cache_key );
delete_site_transient( 'update_plugins' );
}
}
}

View file

@ -59,25 +59,15 @@ if ( ! class_exists( 'AI_Translator_Admin' ) ) {
*/ */
private $settings; private $settings;
/**
* Manager presence notice handler.
*
* @since 1.2.2
* @var AI_Translator_Manager_Notice
*/
private $manager_notice;
/** /**
* Constructor. * Constructor.
* *
* @since 1.0.0 * @since 1.0.0
* *
* @param AI_Translator_Settings $settings Settings handler. * @param AI_Translator_Settings $settings Settings handler.
* @param AI_Translator_Manager_Notice $manager_notice Manager notice handler.
*/ */
public function __construct( AI_Translator_Settings $settings, AI_Translator_Manager_Notice $manager_notice ) { public function __construct( AI_Translator_Settings $settings ) {
$this->settings = $settings; $this->settings = $settings;
$this->manager_notice = $manager_notice;
} }
/** /**
@ -205,8 +195,6 @@ if ( ! class_exists( 'AI_Translator_Admin' ) ) {
<div class="wrap"> <div class="wrap">
<h1><?php echo esc_html__( 'AI Translator Settings', 'robotstxt-ai-translator' ); ?></h1> <h1><?php echo esc_html__( 'AI Translator Settings', 'robotstxt-ai-translator' ); ?></h1>
<?php $this->manager_notice->render_settings_notice(); ?>
<?php if ( $updated ) : ?> <?php if ( $updated ) : ?>
<div class="notice notice-success is-dismissible"> <div class="notice notice-success is-dismissible">
<p><?php echo esc_html__( 'Settings saved.', 'robotstxt-ai-translator' ); ?></p> <p><?php echo esc_html__( 'Settings saved.', 'robotstxt-ai-translator' ); ?></p>
@ -341,8 +329,6 @@ if ( ! class_exists( 'AI_Translator_Admin' ) ) {
<div class="wrap"> <div class="wrap">
<h1><?php echo esc_html__( 'AI Translator Network Settings', 'robotstxt-ai-translator' ); ?></h1> <h1><?php echo esc_html__( 'AI Translator Network Settings', 'robotstxt-ai-translator' ); ?></h1>
<?php $this->manager_notice->render_settings_notice(); ?>
<?php if ( $updated ) : ?> <?php if ( $updated ) : ?>
<div class="notice notice-success is-dismissible"> <div class="notice notice-success is-dismissible">
<p><?php echo esc_html__( 'Network settings saved.', 'robotstxt-ai-translator' ); ?></p> <p><?php echo esc_html__( 'Network settings saved.', 'robotstxt-ai-translator' ); ?></p>

View file

@ -1,191 +0,0 @@
<?php
/**
* Manager (by ROBOTSTXT) presence detection and admin notices.
*
* Updates for the ROBOTSTXT plugin ecosystem are delivered through
* Manager (by ROBOTSTXT). When Manager is missing or inactive, this
* component nudges the administrator:
*
* - On the Plugins list screens (site and network): a dismissible admin notice.
* - On this plugin's settings pages: a persistent (non-dismissible) warning.
*
* @package ROBOTSTXT\AI_Translator
* @since 1.2.2
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'AI_Translator_Manager_Notice' ) ) {
/**
* Detects Manager (by ROBOTSTXT) and renders admin notices.
*
* @since 1.2.2
*/
class AI_Translator_Manager_Notice {
/**
* Manager plugin slug (directory name).
*
* @since 1.2.2
* @var string
*/
const MANAGER_SLUG = 'robotstxt-manager';
/**
* Manager plugin page on the ROBOTSTXT software site.
*
* @since 1.2.2
* @var string
*/
const MANAGER_URL = 'https://www.robotstxt.software/plugins/robotstxt-manager/';
/**
* Option key storing the dismissed state of the plugins-screen notice.
*
* @since 1.2.2
* @var string
*/
const DISMISSED_OPTION = 'ai_translator_manager_notice_dismissed';
/**
* Registers the WordPress hooks.
*
* @since 1.2.2
*
* @return void
*/
public function register() {
add_action( 'admin_init', array( $this, 'handle_dismiss' ) );
add_action( 'admin_notices', array( $this, 'render_plugins_screen_notice' ) );
add_action( 'network_admin_notices', array( $this, 'render_plugins_screen_notice' ) );
}
/**
* Returns whether Manager (by ROBOTSTXT) is installed and active.
*
* Uses the ecosystem presence constant (Manager 1.6.2+) and falls back
* to a plugin-list scan for older Manager versions.
*
* @since 1.2.2
* @since 1.2.3 Added the ROBOTSTXT_MANAGER_NOTICED presence-constant check.
*
* @return bool True when Manager is present and activated.
*/
public function is_manager_active() {
if ( defined( 'ROBOTSTXT_MANAGER_NOTICED' ) && ROBOTSTXT_MANAGER_NOTICED ) {
return true;
}
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$all_plugins = get_plugins();
foreach ( $all_plugins as $file => $data ) {
$slug = dirname( $file );
if ( '.' === $slug ) {
$slug = basename( $file, '.php' );
}
if ( self::MANAGER_SLUG === $slug ) {
return is_plugin_active( $file );
}
}
return false;
}
/**
* Persists the dismissal of the plugins-screen notice, then redirects
* back to a clean URL.
*
* @since 1.2.2
*
* @return void
*/
public function handle_dismiss() {
if ( ! isset( $_GET['ai_translator_dismiss_manager_notice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- verified below before any state change.
return;
}
check_admin_referer( 'ai_translator_dismiss_manager_notice' );
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
update_option( self::DISMISSED_OPTION, '1', false );
wp_safe_redirect( remove_query_arg( array( 'ai_translator_dismiss_manager_notice', '_wpnonce' ) ) );
exit;
}
/**
* Renders the dismissible notice on the Plugins list screens when
* Manager is missing or inactive.
*
* @since 1.2.2
*
* @return void
*/
public function render_plugins_screen_notice() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
if ( ! is_object( $screen ) || ! in_array( $screen->id, array( 'plugins', 'plugins-network' ), true ) ) {
return;
}
if ( $this->is_manager_active() ) {
return;
}
if ( '1' === get_option( self::DISMISSED_OPTION, '' ) ) {
return;
}
$dismiss_url = wp_nonce_url(
add_query_arg( 'ai_translator_dismiss_manager_notice', '1' ),
'ai_translator_dismiss_manager_notice'
);
printf(
'<div class="notice notice-warning"><p>%1$s <a href="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a> &mdash; <a href="%4$s">%5$s</a></p></div>',
esc_html__( 'To get updates for the ROBOTSTXT plugins, the plugin below must be installed and active:', 'robotstxt-ai-translator' ),
esc_url( self::MANAGER_URL ),
esc_html__( 'Manager (by ROBOTSTXT)', 'robotstxt-ai-translator' ),
esc_url( $dismiss_url ),
esc_html__( 'Dismiss this notice', 'robotstxt-ai-translator' )
);
}
/**
* Renders the persistent (non-dismissible) warning for the settings
* pages when Manager is missing or inactive.
*
* @since 1.2.2
*
* @return void
*/
public function render_settings_notice() {
if ( $this->is_manager_active() ) {
return;
}
printf(
'<div class="notice notice-warning inline"><p>%1$s <a href="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a></p></div>',
esc_html__( 'To get updates for the ROBOTSTXT plugins, the plugin below must be installed and active:', 'robotstxt-ai-translator' ),
esc_url( self::MANAGER_URL ),
esc_html__( 'Manager (by ROBOTSTXT)', 'robotstxt-ai-translator' )
);
}
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,16 +1,15 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.3\n" "Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.0\n"
"Report-Msgid-Bugs-To: https://www.robotstxt.software/plugins/robotstxt-ai-" "Report-Msgid-Bugs-To: https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator\n"
"translator/\n"
"POT-Creation-Date: 2026-08-24T11:03:38+00:00\n"
"PO-Revision-Date: 2026-08-24 11:17+0000\n"
"Last-Translator: ROBOTSTXT <hello@robotstxt.es>\n" "Last-Translator: ROBOTSTXT <hello@robotstxt.es>\n"
"Language-Team: Catalan\n" "Language-Team: Catalan\n"
"Language: ca\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2026-05-23T10:07:42+00:00\n"
"PO-Revision-Date: 2026-05-23 10:30+0000\n"
"Language: ca\n"
"X-Generator: hand-written\n" "X-Generator: hand-written\n"
"X-Domain: robotstxt-ai-translator\n" "X-Domain: robotstxt-ai-translator\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
@ -20,353 +19,218 @@ msgstr ""
msgid "AI Translator (by ROBOTSTXT)" msgid "AI Translator (by ROBOTSTXT)"
msgstr "AI Translator (by ROBOTSTXT)" msgstr "AI Translator (by ROBOTSTXT)"
#. Plugin URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://www.robotstxt.software/plugins/robotstxt-ai-translator/"
msgstr ""
#. Description of the plugin
#: robotstxt-ai-translator.php
msgid ""
"Translate post titles and content from the editor using the native WordPress "
"AI client (available in WP 7.0+). Multisite-ready with global or per-site "
"configuration."
msgstr ""
"Tradueix títols i contingut de les entrades des de l'editor usant el client "
"d'IA natiu de WordPress (disponible al WP 7.0+). Preparat per a multilloc "
"amb configuració global o per lloc."
#. Author of the plugin #. Author of the plugin
#: robotstxt-ai-translator.php #: robotstxt-ai-translator.php
msgid "ROBOTSTXT" msgid "ROBOTSTXT"
msgstr "ROBOTSTXT" msgstr "ROBOTSTXT"
#. Author URI of the plugin #: includes/class-ai-translator-admin.php:112
#: robotstxt-ai-translator.php #: includes/class-ai-translator-admin.php:113
msgid "https://www.robotstxt.software/" #: includes/class-ai-translator-admin.php:130
msgstr "" #: includes/class-ai-translator-admin.php:131
#: includes/class-ai-translator-editor-ui.php:294
#: includes/class-ai-translator-admin.php:122 #: includes/class-ai-translator-editor-ui.php:446
#: includes/class-ai-translator-admin.php:123
#: includes/class-ai-translator-admin.php:140
#: includes/class-ai-translator-admin.php:141
#: includes/class-ai-translator-editor-ui.php:402
#: includes/class-ai-translator-editor-ui.php:558
msgid "AI Translator" msgid "AI Translator"
msgstr "AI Translator" msgstr "AI Translator"
#: includes/class-ai-translator-admin.php:163 #: includes/class-ai-translator-admin.php:153
#: includes/class-ai-translator-admin.php:181 #: includes/class-ai-translator-admin.php:171
msgid "Settings" msgid "Settings"
msgstr "Ajustaments" msgstr "Ajustaments"
#: includes/class-ai-translator-admin.php:197 #: includes/class-ai-translator-admin.php:187
#: includes/class-ai-translator-admin.php:333 #: includes/class-ai-translator-admin.php:287
msgid "You do not have permission to access this page." msgid "You do not have permission to access this page."
msgstr "No tens permís per accedir a aquesta pàgina." msgstr "No tens permís per accedir a aquesta pàgina."
#: includes/class-ai-translator-admin.php:206 #: includes/class-ai-translator-admin.php:196
msgid "AI Translator Settings" msgid "AI Translator Settings"
msgstr "Ajustaments d'AI Translator" msgstr "Ajustaments d'AI Translator"
#: includes/class-ai-translator-admin.php:212 #: includes/class-ai-translator-admin.php:200
msgid "Settings saved." msgid "Settings saved."
msgstr "Ajustaments desats." msgstr "Ajustaments desats."
#: includes/class-ai-translator-admin.php:223 #: includes/class-ai-translator-admin.php:211
#: includes/class-ai-translator-admin.php:226 #: includes/class-ai-translator-admin.php:214
#: includes/class-ai-translator-admin.php:378 #: includes/class-ai-translator-admin.php:330
#: includes/class-ai-translator-admin.php:382 #: includes/class-ai-translator-admin.php:334
msgid "Translation fields" msgid "Translation fields"
msgstr "Camps a traduir" msgstr "Camps a traduir"
#: includes/class-ai-translator-admin.php:230 #: includes/class-ai-translator-admin.php:218
#: includes/class-ai-translator-admin.php:386 #: includes/class-ai-translator-admin.php:338
#: includes/class-ai-translator-editor-ui.php:565 #: includes/class-ai-translator-editor-ui.php:453
msgid "Translate title" msgid "Translate title"
msgstr "Tradueix el títol" msgstr "Tradueix el títol"
#: includes/class-ai-translator-admin.php:235 #: includes/class-ai-translator-admin.php:223
#: includes/class-ai-translator-admin.php:391 #: includes/class-ai-translator-admin.php:343
#: includes/class-ai-translator-editor-ui.php:566 #: includes/class-ai-translator-editor-ui.php:454
msgid "Translate content" msgid "Translate content"
msgstr "Tradueix el contingut" msgstr "Tradueix el contingut"
#: includes/class-ai-translator-admin.php:240 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:396 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-editor-ui.php:567 #: includes/class-ai-translator-admin.php:239
msgid "Translate excerpt"
msgstr "Traduir l'extracte"
#. translators: 1: title default, 2: content default, 3: excerpt default.
#: includes/class-ai-translator-admin.php:248
#, php-format
msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s."
msgstr ""
"Valors predeterminats de la xarxa: títol %1$s, contingut %2$s, extracte %3$s."
#: includes/class-ai-translator-admin.php:249
#: includes/class-ai-translator-admin.php:250
#: includes/class-ai-translator-admin.php:251
msgid "enabled" msgid "enabled"
msgstr "activat" msgstr "activat"
#: includes/class-ai-translator-admin.php:249 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:250 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-admin.php:251 #: includes/class-ai-translator-admin.php:239
msgid "disabled" msgid "disabled"
msgstr "desactivat" msgstr "desactivat"
#: includes/class-ai-translator-admin.php:262
#: includes/class-ai-translator-admin.php:408
msgid "Request timeout"
msgstr "Temps màxim de resposta"
#: includes/class-ai-translator-admin.php:275
#: includes/class-ai-translator-admin.php:421
msgid "seconds"
msgstr "segons"
#. translators: %d: PHP max_execution_time in seconds.
#: includes/class-ai-translator-admin.php:283
#: includes/class-ai-translator-admin.php:429
#, php-format
msgid ""
"Maximum time the server waits for an AI response. PHP max_execution_time is "
"%d s — values above this have no effect."
msgstr ""
"Temps màxim que el servidor espera una resposta de la IA. El "
"max_execution_time de PHP és de %d s — els valors superiors no tenen efecte."
#: includes/class-ai-translator-admin.php:287
#: includes/class-ai-translator-admin.php:433
msgid ""
"Maximum time the server waits for an AI response. PHP max_execution_time is "
"unlimited."
msgstr ""
"Temps màxim que el servidor espera una resposta de la IA. El "
"max_execution_time de PHP és il·limitat."
#: includes/class-ai-translator-admin.php:296 #: includes/class-ai-translator-admin.php:296
#: includes/class-ai-translator-admin.php:299
#: includes/class-ai-translator-admin.php:442
#: includes/class-ai-translator-admin.php:445
msgid "MultilingualPress"
msgstr "MultilingualPress"
#: includes/class-ai-translator-admin.php:303
#: includes/class-ai-translator-admin.php:449
msgid "Auto-translate new connected posts"
msgstr "Traduir automàticament les entrades connectades noves"
#: includes/class-ai-translator-admin.php:307
#: includes/class-ai-translator-admin.php:453
msgid ""
"When MultilingualPress creates a new connected post, automatically translate "
"its enabled fields into the target site's language. The translation runs "
"synchronously during save."
msgstr ""
"Quan MultilingualPress crea una entrada connectada nova, tradueix "
"automàticament els camps activats a l'idioma del lloc de destinació. La "
"traducció s'executa de manera síncrona en desar."
#: includes/class-ai-translator-admin.php:342
msgid "AI Translator Network Settings" msgid "AI Translator Network Settings"
msgstr "Ajustaments de xarxa d'AI Translator" msgstr "Ajustaments de xarxa d'AI Translator"
#: includes/class-ai-translator-admin.php:348 #: includes/class-ai-translator-admin.php:300
msgid "Network settings saved." msgid "Network settings saved."
msgstr "Ajustaments de xarxa desats." msgstr "Ajustaments de xarxa desats."
#: includes/class-ai-translator-admin.php:358 #: includes/class-ai-translator-admin.php:310
#: includes/class-ai-translator-admin.php:361 #: includes/class-ai-translator-admin.php:313
msgid "Configuration mode" msgid "Configuration mode"
msgstr "Mode de configuració" msgstr "Mode de configuració"
#: includes/class-ai-translator-admin.php:365 #: includes/class-ai-translator-admin.php:317
msgid "Global configuration: a single setting applies to every site." msgid "Global configuration: a single setting applies to every site."
msgstr "Configuració global: un sol ajustament s'aplica a tots els llocs." msgstr "Configuració global: un sol ajustament s'aplica a tots els llocs."
#: includes/class-ai-translator-admin.php:370 #: includes/class-ai-translator-admin.php:322
msgid "Per-site configuration: each site can override these defaults." msgid "Per-site configuration: each site can override these defaults."
msgstr "" msgstr "Configuració per lloc: cada lloc pot sobreescriure aquests valors predeterminats."
"Configuració per lloc: cada lloc pot sobreescriure aquests valors "
"predeterminats."
#: includes/class-ai-translator-admin.php:400 #: includes/class-ai-translator-admin.php:352
msgid "" msgid "In global mode this is the configuration for the whole network. In per-site mode these values are used as defaults for sites that have not been configured individually."
"In global mode this is the configuration for the whole network. In per-site " msgstr "En mode global aquesta és la configuració per a tota la xarxa. En mode per lloc aquests valors s'utilitzen com a predeterminats per als llocs que no s'hagin configurat individualment."
"mode these values are used as defaults for sites that have not been "
"configured individually."
msgstr ""
"En mode global aquesta és la configuració per a tota la xarxa. En mode per "
"lloc aquests valors s'utilitzen com a predeterminats per als llocs que no "
"s'hagin configurat individualment."
#: includes/class-ai-translator-admin.php:479 #: includes/class-ai-translator-admin.php:397
#: includes/class-ai-translator-admin.php:511 #: includes/class-ai-translator-admin.php:429
msgid "You do not have permission to perform this action." msgid "You do not have permission to perform this action."
msgstr "No tens permís per dur a terme aquesta acció." msgstr "No tens permís per dur a terme aquesta acció."
#: includes/class-ai-translator-admin.php:555 #: includes/class-ai-translator-admin.php:473
msgid "Recommended models" msgid "Recommended models"
msgstr "Models recomanats" msgstr "Models recomanats"
#: includes/class-ai-translator-admin.php:558 #: includes/class-ai-translator-admin.php:476
msgid "" msgid "This plugin does not call AI providers directly. Configure your preferred provider in the WordPress AI plugin settings. The table below is a guide to help you pick a model based on your translation use case."
"This plugin does not call AI providers directly. Configure your preferred " msgstr "Aquest connector no truca directament als proveïdors d'IA. Configura el teu proveïdor preferit als ajustaments del connector WordPress AI. La taula següent és una guia per ajudar-te a triar un model segons el teu cas d'ús de traducció."
"provider in the WordPress AI plugin settings. The table below is a guide to "
"help you pick a model based on your translation use case."
msgstr ""
"Aquest connector no truca directament als proveïdors d'IA. Configura el teu "
"proveïdor preferit als ajustaments del connector WordPress AI. La taula "
"següent és una guia per ajudar-te a triar un model segons el teu cas d'ús de "
"traducció."
#: includes/class-ai-translator-admin.php:564 #: includes/class-ai-translator-admin.php:482
msgid "Use case" msgid "Use case"
msgstr "Cas d'ús" msgstr "Cas d'ús"
#: includes/class-ai-translator-admin.php:565 #: includes/class-ai-translator-admin.php:483
msgid "Recommended model" msgid "Recommended model"
msgstr "Model recomanat" msgstr "Model recomanat"
#: includes/class-ai-translator-admin.php:566 #: includes/class-ai-translator-admin.php:484
msgid "Why" msgid "Why"
msgstr "Per què" msgstr "Per què"
#: includes/class-ai-translator-admin.php:581 #: includes/class-ai-translator-admin.php:499
msgid "" msgid "These recommendations are based on public benchmarks and community feedback as of the plugin release date. They may change as providers update their models."
"These recommendations are based on public benchmarks and community feedback " msgstr "Aquestes recomanacions es basen en benchmarks públics i comentaris de la comunitat en la data de publicació del connector. Poden canviar a mesura que els proveïdors actualitzin els seus models."
"as of the plugin release date. They may change as providers update their "
"models."
msgstr ""
"Aquestes recomanacions es basen en benchmarks públics i comentaris de la "
"comunitat en la data de publicació del connector. Poden canviar a mesura que "
"els proveïdors actualitzin els seus models."
#: includes/class-ai-translator-admin.php:596 #: includes/class-ai-translator-admin.php:514
msgid "European languages (ES, CA, FR, DE, IT, PT)" msgid "European languages (ES, CA, FR, DE, IT, PT)"
msgstr "Llengües europees (ES, CA, FR, DE, IT, PT)" msgstr "Llengües europees (ES, CA, FR, DE, IT, PT)"
#: includes/class-ai-translator-admin.php:597 #: includes/class-ai-translator-admin.php:515
msgid "DeepL API Pro" msgid "DeepL API Pro"
msgstr "DeepL API Pro" msgstr "DeepL API Pro"
#: includes/class-ai-translator-admin.php:598 #: includes/class-ai-translator-admin.php:516
msgid "" msgid "Best fluency and naturalness (92/100 in benchmarks). Formality control and custom glossaries."
"Best fluency and naturalness (92/100 in benchmarks). Formality control and " msgstr "La millor fluïdesa i naturalitat (92/100 en benchmarks). Control de formalitat i glossaris personalitzats."
"custom glossaries."
msgstr ""
"La millor fluïdesa i naturalitat (92/100 en benchmarks). Control de "
"formalitat i glossaris personalitzats."
#: includes/class-ai-translator-admin.php:601 #: includes/class-ai-translator-admin.php:519
msgid "Asian languages (ZH, JA, KO)" msgid "Asian languages (ZH, JA, KO)"
msgstr "Llengües asiàtiques (ZH, JA, KO)" msgstr "Llengües asiàtiques (ZH, JA, KO)"
#: includes/class-ai-translator-admin.php:602 #: includes/class-ai-translator-admin.php:520
msgid "GPT-4o / GPT-5 or Claude Sonnet 4" msgid "GPT-4o / GPT-5 or Claude Sonnet 4"
msgstr "GPT-4o / GPT-5 o Claude Sonnet 4" msgstr "GPT-4o / GPT-5 o Claude Sonnet 4"
#: includes/class-ai-translator-admin.php:603 #: includes/class-ai-translator-admin.php:521
msgid "" msgid "Better handling of implicit subjects, honorifics, and cultural references. DeepL falls behind here."
"Better handling of implicit subjects, honorifics, and cultural references. " msgstr "Millor gestió dels subjectes implícits, els honorífics i les referències culturals. DeepL queda enrere aquí."
"DeepL falls behind here."
msgstr ""
"Millor gestió dels subjectes implícits, els honorífics i les referències "
"culturals. DeepL queda enrere aquí."
#: includes/class-ai-translator-admin.php:606 #: includes/class-ai-translator-admin.php:524
msgid "Marketing / brand tone" msgid "Marketing / brand tone"
msgstr "Màrqueting / to de marca" msgstr "Màrqueting / to de marca"
#: includes/class-ai-translator-admin.php:607 #: includes/class-ai-translator-admin.php:525
msgid "Claude Sonnet 4 / Opus 4" msgid "Claude Sonnet 4 / Opus 4"
msgstr "Claude Sonnet 4 / Opus 4" msgstr "Claude Sonnet 4 / Opus 4"
#: includes/class-ai-translator-admin.php:608 #: includes/class-ai-translator-admin.php:526
msgid "" msgid "Better preservation of tone, brand voice, and nuance. Ideal for creative copy."
"Better preservation of tone, brand voice, and nuance. Ideal for creative " msgstr "Preserva millor el to, la veu de la marca i els matisos. Ideal per a copy creatiu."
"copy."
msgstr ""
"Preserva millor el to, la veu de la marca i els matisos. Ideal per a copy "
"creatiu."
#: includes/class-ai-translator-admin.php:611 #: includes/class-ai-translator-admin.php:529
msgid "Technical documentation / code" msgid "Technical documentation / code"
msgstr "Documentació tècnica / codi" msgstr "Documentació tècnica / codi"
#: includes/class-ai-translator-admin.php:612 #: includes/class-ai-translator-admin.php:530
msgid "GPT-4o / GPT-5" msgid "GPT-4o / GPT-5"
msgstr "GPT-4o / GPT-5" msgstr "GPT-4o / GPT-5"
#: includes/class-ai-translator-admin.php:613 #: includes/class-ai-translator-admin.php:531
msgid "" msgid "Higher accuracy with variables, structured formats, and technical terminology."
"Higher accuracy with variables, structured formats, and technical " msgstr "Major precisió amb variables, formats estructurats i terminologia tècnica."
"terminology."
msgstr ""
"Major precisió amb variables, formats estructurats i terminologia tècnica."
#: includes/class-ai-translator-admin.php:616 #: includes/class-ai-translator-admin.php:534
msgid "Long documents (100+ pages)" msgid "Long documents (100+ pages)"
msgstr "Documents llargs (més de 100 pàgines)" msgstr "Documents llargs (més de 100 pàgines)"
#: includes/class-ai-translator-admin.php:617 #: includes/class-ai-translator-admin.php:535
msgid "Gemini 2.5 Pro" msgid "Gemini 2.5 Pro"
msgstr "Gemini 2.5 Pro" msgstr "Gemini 2.5 Pro"
#: includes/class-ai-translator-admin.php:618 #: includes/class-ai-translator-admin.php:536
msgid "" msgid "1M token context window. Maintains terminological consistency across long texts."
"1M token context window. Maintains terminological consistency across long " msgstr "Finestra de context d'1 milió de tokens. Manté la consistència terminològica en textos llargs."
"texts."
msgstr ""
"Finestra de context d'1 milió de tokens. Manté la consistència terminològica "
"en textos llargs."
#: includes/class-ai-translator-admin.php:621 #: includes/class-ai-translator-admin.php:539
msgid "High volume / low cost" msgid "High volume / low cost"
msgstr "Alt volum / baix cost" msgstr "Alt volum / baix cost"
#: includes/class-ai-translator-admin.php:622 #: includes/class-ai-translator-admin.php:540
msgid "DeepSeek-V3" msgid "DeepSeek-V3"
msgstr "DeepSeek-V3" msgstr "DeepSeek-V3"
#: includes/class-ai-translator-admin.php:623 #: includes/class-ai-translator-admin.php:541
msgid "" msgid "Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/GPT)."
"Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/" msgstr "Qualitat comparable a GPT-5 a ~0,14 $/M tokens (entre 20 i 50 vegades més barat que Claude/GPT)."
"GPT)."
msgstr ""
"Qualitat comparable a GPT-5 a ~0,14 $/M tokens (entre 20 i 50 vegades més "
"barat que Claude/GPT)."
#: includes/class-ai-translator-admin.php:626 #: includes/class-ai-translator-admin.php:544
msgid "Rare / indigenous languages" msgid "Rare / indigenous languages"
msgstr "Llengües rares / indígenes" msgstr "Llengües rares / indígenes"
#: includes/class-ai-translator-admin.php:627 #: includes/class-ai-translator-admin.php:545
msgid "Claude Sonnet or Taskade Translate (multi-model routing)" msgid "Claude Sonnet or Taskade Translate (multi-model routing)"
msgstr "Claude Sonnet o Taskade Translate (encaminament multimodel)" msgstr "Claude Sonnet o Taskade Translate (encaminament multimodel)"
#: includes/class-ai-translator-admin.php:628 #: includes/class-ai-translator-admin.php:546
msgid "Better coverage for uncommon language pairs." msgid "Better coverage for uncommon language pairs."
msgstr "Millor cobertura en parells de llengües poc habituals." msgstr "Millor cobertura en parells de llengües poc habituals."
#: includes/class-ai-translator-admin.php:631 #: includes/class-ai-translator-admin.php:549
msgid "Maximum coverage (133+ languages)" msgid "Maximum coverage (133+ languages)"
msgstr "Cobertura màxima (més de 133 llengües)" msgstr "Cobertura màxima (més de 133 llengües)"
#: includes/class-ai-translator-admin.php:632 #: includes/class-ai-translator-admin.php:550
msgid "Google Cloud Translation" msgid "Google Cloud Translation"
msgstr "Google Cloud Translation" msgstr "Google Cloud Translation"
#: includes/class-ai-translator-admin.php:633 #: includes/class-ai-translator-admin.php:551
msgid "" msgid "The most complete option, though with slightly lower quality on European languages."
"The most complete option, though with slightly lower quality on European " msgstr "L'opció més completa, tot i que amb una qualitat lleugerament inferior en llengües europees."
"languages."
msgstr ""
"L'opció més completa, tot i que amb una qualitat lleugerament inferior en "
"llengües europees."
#: includes/class-ai-translator-cli.php:120 #: includes/class-ai-translator-cli.php:120
msgid "The --locale flag is required." msgid "The --locale flag is required."
@ -376,37 +240,16 @@ msgstr "El paràmetre --locale és obligatori."
msgid "The --post-id and --post-type flags are mutually exclusive." msgid "The --post-id and --post-type flags are mutually exclusive."
msgstr "Els paràmetres --post-id i --post-type són mútuament excloents." msgstr "Els paràmetres --post-id i --post-type són mútuament excloents."
#: includes/class-ai-translator-cli.php:141
msgid "No user context. Pass --user=<id|login> so post updates carry an author and capability checks apply."
msgstr "Sense context d'usuari. Passa --user=<id|login> perquè les actualitzacions d'entrades tinguin autor i s'apliquin les comprovacions de capacitats."
#. translators: %s: locale code. #. translators: %s: locale code.
#: includes/class-ai-translator-cli.php:133 #: includes/class-ai-translator-cli.php:133
#, php-format #, php-format
msgid "The locale %s is not installed on this site." msgid "The locale %s is not installed on this site."
msgstr "La llengua %s no està instal·lada en aquest lloc." msgstr "La llengua %s no està instal·lada en aquest lloc."
#: includes/class-ai-translator-cli.php:141
msgid ""
"No user context. Pass --user=<id|login> so post updates carry an author and "
"capability checks apply."
msgstr ""
"Sense context d'usuari. Passa --user=<id|login> perquè les actualitzacions "
"d'entrades tinguin autor i s'apliquin les comprovacions de capacitats."
#: includes/class-ai-translator-cli.php:145
#: includes/class-ai-translator-editor-ui.php:427
#: includes/class-ai-translator-editor-ui.php:563
#: includes/class-ai-translator-translator.php:135
msgid "AI features are disabled for this WordPress installation."
msgstr ""
"Les funcions d'IA estan desactivades per a aquesta instal·lació de WordPress."
#: includes/class-ai-translator-cli.php:149
#: includes/class-ai-translator-translator.php:142
msgid ""
"No AI provider is configured for text generation. Open Settings → AI to set "
"one up."
msgstr ""
"No hi ha cap proveïdor d'IA configurat per a la generació de text. Obre "
"Ajustos → IA per configurar-ne un."
#: includes/class-ai-translator-cli.php:155 #: includes/class-ai-translator-cli.php:155
msgid "No translation fields are enabled in the plugin settings." msgid "No translation fields are enabled in the plugin settings."
msgstr "No hi ha cap camp de traducció activat als ajustaments del connector." msgstr "No hi ha cap camp de traducció activat als ajustaments del connector."
@ -421,131 +264,169 @@ msgstr "Cap entrada coincideix amb els criteris donats."
msgid "%1$d translated, %2$d failed (locale: %3$s)." msgid "%1$d translated, %2$d failed (locale: %3$s)."
msgstr "%1$d traduïdes, %2$d amb errors (llengua: %3$s)." msgstr "%1$d traduïdes, %2$d amb errors (llengua: %3$s)."
#: includes/class-ai-translator-editor-ui.php:229 #: includes/class-ai-translator-editor-ui.php:160
#: includes/class-ai-translator-editor-ui.php:298
msgid "Post not found."
msgstr "Entrada no trobada."
#: includes/class-ai-translator-editor-ui.php:239
#: includes/class-ai-translator-editor-ui.php:307
msgid "The selected language is not installed on this site."
msgstr "La llengua seleccionada no està instal·lada en aquest lloc."
#: includes/class-ai-translator-editor-ui.php:268
msgid "Sorry, you are not allowed to edit this post." msgid "Sorry, you are not allowed to edit this post."
msgstr "Ho sentim, no tens permís per editar aquesta entrada." msgstr "Ho sentim, no tens permís per editar aquesta entrada."
#: includes/class-ai-translator-editor-ui.php:329 #: includes/class-ai-translator-editor-ui.php:190
msgid "" msgid "Post not found."
"No translatable fields were selected, or the requested fields are disabled " msgstr "Entrada no trobada."
"in the settings."
msgstr ""
"No s'ha seleccionat cap camp traduïble, o els camps sol·licitats estan "
"desactivats als ajustaments."
#: includes/class-ai-translator-editor-ui.php:429 #: includes/class-ai-translator-editor-ui.php:199
#: includes/class-ai-translator-editor-ui.php:562 msgid "The selected language is not installed on this site."
msgstr "La llengua seleccionada no està instal·lada en aquest lloc."
#: includes/class-ai-translator-editor-ui.php:221
msgid "No translatable fields were selected, or the requested fields are disabled in the settings."
msgstr "No s'ha seleccionat cap camp traduïble, o els camps sol·licitats estan desactivats als ajustaments."
#: includes/class-ai-translator-editor-ui.php:321
#: includes/class-ai-translator-editor-ui.php:450
msgid "No translation fields are enabled in settings." msgid "No translation fields are enabled in settings."
msgstr "No hi ha cap camp de traducció activat als ajustaments." msgstr "No hi ha cap camp de traducció activat als ajustaments."
#: includes/class-ai-translator-editor-ui.php:431 #: includes/class-ai-translator-editor-ui.php:323
#: includes/class-ai-translator-editor-ui.php:561 #: includes/class-ai-translator-editor-ui.php:449
msgid "No languages are installed on this site." msgid "No languages are installed on this site."
msgstr "No hi ha cap llengua instal·lada en aquest lloc." msgstr "No hi ha cap llengua instal·lada en aquest lloc."
#: includes/class-ai-translator-editor-ui.php:434 #: includes/class-ai-translator-editor-ui.php:326
#: includes/class-ai-translator-editor-ui.php:557 #: includes/class-ai-translator-editor-ui.php:445
msgid "Target language" msgid "Target language"
msgstr "Llengua de destinació" msgstr "Llengua de destinació"
#: includes/class-ai-translator-editor-ui.php:444 #: includes/class-ai-translator-editor-ui.php:336
#: includes/class-ai-translator-editor-ui.php:553 #: includes/class-ai-translator-editor-ui.php:443
msgid "Translate" msgid "Translate"
msgstr "Tradueix" msgstr "Tradueix"
#: includes/class-ai-translator-editor-ui.php:449 #: includes/class-ai-translator-editor-ui.php:341
msgid "" msgid "Save the post before translating to ensure the latest content is used. The translation replaces the current title and/or content."
"Save the post before translating to ensure the latest content is used. The " msgstr "Desa l'entrada abans de traduir perquè s'utilitzi la versió més recent. La traducció substitueix el títol i/o el contingut actuals."
"translation replaces the current title and/or content."
msgstr ""
"Desa l'entrada abans de traduir perquè s'utilitzi la versió més recent. La "
"traducció substitueix el títol i/o el contingut actuals."
#: includes/class-ai-translator-editor-ui.php:554 #: includes/class-ai-translator-editor-ui.php:444
msgid "Translating…" msgid "Translating…"
msgstr "Traduint…" msgstr "Traduint…"
#. translators: 1: number of chunks translated so far, 2: total number of chunks. #: includes/class-ai-translator-editor-ui.php:447
#: includes/class-ai-translator-editor-ui.php:556
msgid "Translating… ({done}/{total})"
msgstr "Traduint… ({done}/{total})"
#: includes/class-ai-translator-editor-ui.php:559
msgid "Translation applied. Review and save the post." msgid "Translation applied. Review and save the post."
msgstr "Traducció aplicada. Revisa i desa l'entrada." msgstr "Traducció aplicada. Revisa i desa l'entrada."
#: includes/class-ai-translator-editor-ui.php:560 #: includes/class-ai-translator-editor-ui.php:448
msgid "Translation failed." msgid "Translation failed."
msgstr "La traducció ha fallat." msgstr "La traducció ha fallat."
#: includes/class-ai-translator-editor-ui.php:564 #: includes/class-ai-translator-editor-ui.php:452
msgid "" msgid "You have unsaved changes. Save the post before translating to ensure the latest content is used."
"You have unsaved changes. Save the post before translating to ensure the " msgstr "Tens canvis sense desar. Desa l'entrada abans de traduir perquè s'utilitzi la versió més recent."
"latest content is used."
msgstr ""
"Tens canvis sense desar. Desa l'entrada abans de traduir perquè s'utilitzi "
"la versió més recent."
#: includes/class-ai-translator-manager-notice.php:162 #: includes/class-ai-translator-translator.php:102
#: includes/class-ai-translator-manager-notice.php:185
msgid ""
"To get updates for the ROBOTSTXT plugins, the plugin below must be installed "
"and active:"
msgstr ""
"Per rebre actualitzacions dels plugins de ROBOTSTXT, el plugin següent ha "
"d'estar instal·lat i actiu:"
#: includes/class-ai-translator-manager-notice.php:164
#: includes/class-ai-translator-manager-notice.php:187
msgid "Manager (by ROBOTSTXT)"
msgstr "Manager (by ROBOTSTXT)"
#: includes/class-ai-translator-manager-notice.php:166
msgid "Dismiss this notice"
msgstr "Descartar aquest avís"
#: includes/class-ai-translator-translator.php:151
msgid "The target language is not installed on this site." msgid "The target language is not installed on this site."
msgstr "La llengua de destinació no està instal·lada en aquest lloc." msgstr "La llengua de destinació no està instal·lada en aquest lloc."
#. translators: %s: target language name. #. translators: %s: target language name.
#: includes/class-ai-translator-translator.php:157 #: includes/class-ai-translator-translator.php:108
#, php-format #, php-format
msgid "" msgid "You are a professional translator. Translate the user message into %s. Preserve any HTML, shortcodes, line breaks, and Markdown exactly as they appear. Return only the translated text, without explanations, prefaces, or quotation marks."
"You are a professional translator. Translate the user message into %s. " msgstr "Ets un traductor professional. Tradueix el missatge de l'usuari al %s. Preserva l'HTML, els shortcodes, els salts de línia i el Markdown exactament com apareixen. Retorna només el text traduït, sense explicacions, prefacis ni cometes."
"Preserve any HTML, shortcodes, line breaks, and Markdown exactly as they "
"appear. Return only the translated text, without explanations, prefaces, or "
"quotation marks."
msgstr ""
"Ets un traductor professional. Tradueix el missatge de l'usuari al %s. "
"Preserva l'HTML, els shortcodes, els salts de línia i el Markdown exactament "
"com apareixen. Retorna només el text traduït, sense explicacions, prefacis "
"ni cometes."
#: includes/class-ai-translator-translator.php:186 #: includes/class-ai-translator-translator.php:129
msgid "The AI service returned an unexpected response." msgid "The AI service returned an unexpected response."
msgstr "El servei d'IA ha retornat una resposta inesperada." msgstr "El servei d'IA ha retornat una resposta inesperada."
#. translators: %s: Link to the WordPress AI settings page. #: class-robotstxt-updater.php:456
#: robotstxt-ai-translator.php:145 msgid "You do not have sufficient permissions to access this page."
#, php-format msgstr "No tens permisos suficients per accedir a aquesta pàgina."
msgid ""
"AI Translator (by ROBOTSTXT) requires a configured AI provider for text "
"generation. Open %s to set one up."
msgstr ""
"AI Translator (by ROBOTSTXT) requereix un proveïdor d'IA configurat per a la "
"generació de text. Obre %s per configurar-ne un."
#: robotstxt-ai-translator.php:146 #. Plugin URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator"
msgstr ""
#. Description of the plugin
#: robotstxt-ai-translator.php
msgid "Translate post titles and content from the editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration."
msgstr ""
#. Author URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://www.robotstxt.es/"
msgstr ""
#: class-robotstxt-updater.php:452
msgid "Security check failed."
msgstr "Error de verificació de seguretat."
#: includes/class-ai-translator-admin.php:228
#: includes/class-ai-translator-admin.php:348
#: includes/class-ai-translator-editor-ui.php:455
msgid "Translate excerpt"
msgstr "Traduir l'extracte"
#. translators: 1: title default, 2: content default, 3: excerpt default.
#: includes/class-ai-translator-admin.php:236
#, php-format
msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s."
msgstr "Valors predeterminats de la xarxa: títol %1$s, contingut %2$s, extracte %3$s."
#: includes/class-ai-translator-admin.php:250
#: includes/class-ai-translator-admin.php:253
#: includes/class-ai-translator-admin.php:360
#: includes/class-ai-translator-admin.php:363
msgid "MultilingualPress"
msgstr "MultilingualPress"
#: includes/class-ai-translator-admin.php:257
#: includes/class-ai-translator-admin.php:367
msgid "Auto-translate new connected posts"
msgstr "Traduir automàticament les entrades connectades noves"
#: includes/class-ai-translator-admin.php:261
#: includes/class-ai-translator-admin.php:371
msgid "When MultilingualPress creates a new connected post, automatically translate its enabled fields into the target site's language. The translation runs synchronously during save."
msgstr "Quan MultilingualPress crea una entrada connectada nova, tradueix automàticament els camps activats a l'idioma del lloc de destinació. La traducció s'executa de manera síncrona en desar."
#: includes/class-ai-translator-cli.php:145
#: includes/class-ai-translator-editor-ui.php:319
#: includes/class-ai-translator-editor-ui.php:451
#: includes/class-ai-translator-translator.php:86
msgid "AI features are disabled for this WordPress installation."
msgstr "Les funcions d'IA estan desactivades per a aquesta instal·lació de WordPress."
#: includes/class-ai-translator-cli.php:149
#: includes/class-ai-translator-translator.php:93
msgid "No AI provider is configured for text generation. Open Settings → AI to set one up."
msgstr "No hi ha cap proveïdor d'IA configurat per a la generació de text. Obre Ajustos → IA per configurar-ne un."
#. translators: %s: Link to the WordPress AI settings page.
#: robotstxt-ai-translator.php:144
#, php-format
msgid "AI Translator (by ROBOTSTXT) requires a configured AI provider for text generation. Open %s to set one up."
msgstr "AI Translator (by ROBOTSTXT) requereix un proveïdor d'IA configurat per a la generació de text. Obre %s per configurar-ne un."
#: robotstxt-ai-translator.php:145
msgid "Settings → AI" msgid "Settings → AI"
msgstr "Ajustos → IA" msgstr "Ajustos → IA"
#: includes/class-ai-translator-admin.php
msgid "Request timeout"
msgstr "Temps màxim de resposta"
#: includes/class-ai-translator-admin.php
msgid "seconds"
msgstr "segons"
#. translators: %d: PHP max_execution_time in seconds.
#: includes/class-ai-translator-admin.php
#, php-format
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is %d s — values above this have no effect."
msgstr "Temps màxim que el servidor espera una resposta de la IA. El max_execution_time de PHP és de %d s — els valors superiors no tenen efecte."
#: includes/class-ai-translator-admin.php
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is unlimited."
msgstr "Temps màxim que el servidor espera una resposta de la IA. El max_execution_time de PHP és il·limitat."
#. translators: 1: number of chunks translated so far, 2: total number of chunks.
#: includes/class-ai-translator-editor-ui.php
msgid "Translating… ({done}/{total})"
msgstr "Traduint… ({done}/{total})"

File diff suppressed because one or more lines are too long

View file

@ -1,16 +1,15 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.3\n" "Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.0\n"
"Report-Msgid-Bugs-To: https://www.robotstxt.software/plugins/robotstxt-ai-" "Report-Msgid-Bugs-To: https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator\n"
"translator/\n"
"POT-Creation-Date: 2026-08-24T11:03:38+00:00\n"
"PO-Revision-Date: 2026-08-24 11:17+0000\n"
"Last-Translator: ROBOTSTXT <hello@robotstxt.es>\n" "Last-Translator: ROBOTSTXT <hello@robotstxt.es>\n"
"Language-Team: Spanish (Spain)\n" "Language-Team: Spanish (Spain)\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2026-05-23T10:07:42+00:00\n"
"PO-Revision-Date: 2026-05-23 10:30+0000\n"
"Language: es_ES\n"
"X-Generator: hand-written\n" "X-Generator: hand-written\n"
"X-Domain: robotstxt-ai-translator\n" "X-Domain: robotstxt-ai-translator\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
@ -20,355 +19,218 @@ msgstr ""
msgid "AI Translator (by ROBOTSTXT)" msgid "AI Translator (by ROBOTSTXT)"
msgstr "AI Translator (by ROBOTSTXT)" msgstr "AI Translator (by ROBOTSTXT)"
#. Plugin URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://www.robotstxt.software/plugins/robotstxt-ai-translator/"
msgstr ""
#. Description of the plugin
#: robotstxt-ai-translator.php
msgid ""
"Translate post titles and content from the editor using the native WordPress "
"AI client (available in WP 7.0+). Multisite-ready with global or per-site "
"configuration."
msgstr ""
"Traduce títulos y contenido de las entradas desde el editor usando el "
"cliente de IA nativo de WordPress (disponible en WP 7.0+). Preparado para "
"multisitio con configuración global o por sitio."
#. Author of the plugin #. Author of the plugin
#: robotstxt-ai-translator.php #: robotstxt-ai-translator.php
msgid "ROBOTSTXT" msgid "ROBOTSTXT"
msgstr "ROBOTSTXT" msgstr "ROBOTSTXT"
#. Author URI of the plugin #: includes/class-ai-translator-admin.php:112
#: robotstxt-ai-translator.php #: includes/class-ai-translator-admin.php:113
msgid "https://www.robotstxt.software/" #: includes/class-ai-translator-admin.php:130
msgstr "" #: includes/class-ai-translator-admin.php:131
#: includes/class-ai-translator-editor-ui.php:294
#: includes/class-ai-translator-admin.php:122 #: includes/class-ai-translator-editor-ui.php:446
#: includes/class-ai-translator-admin.php:123
#: includes/class-ai-translator-admin.php:140
#: includes/class-ai-translator-admin.php:141
#: includes/class-ai-translator-editor-ui.php:402
#: includes/class-ai-translator-editor-ui.php:558
msgid "AI Translator" msgid "AI Translator"
msgstr "AI Translator" msgstr "AI Translator"
#: includes/class-ai-translator-admin.php:163 #: includes/class-ai-translator-admin.php:153
#: includes/class-ai-translator-admin.php:181 #: includes/class-ai-translator-admin.php:171
msgid "Settings" msgid "Settings"
msgstr "Ajustes" msgstr "Ajustes"
#: includes/class-ai-translator-admin.php:197 #: includes/class-ai-translator-admin.php:187
#: includes/class-ai-translator-admin.php:333 #: includes/class-ai-translator-admin.php:287
msgid "You do not have permission to access this page." msgid "You do not have permission to access this page."
msgstr "No tienes permiso para acceder a esta página." msgstr "No tienes permiso para acceder a esta página."
#: includes/class-ai-translator-admin.php:206 #: includes/class-ai-translator-admin.php:196
msgid "AI Translator Settings" msgid "AI Translator Settings"
msgstr "Ajustes de AI Translator" msgstr "Ajustes de AI Translator"
#: includes/class-ai-translator-admin.php:212 #: includes/class-ai-translator-admin.php:200
msgid "Settings saved." msgid "Settings saved."
msgstr "Ajustes guardados." msgstr "Ajustes guardados."
#: includes/class-ai-translator-admin.php:223 #: includes/class-ai-translator-admin.php:211
#: includes/class-ai-translator-admin.php:226 #: includes/class-ai-translator-admin.php:214
#: includes/class-ai-translator-admin.php:378 #: includes/class-ai-translator-admin.php:330
#: includes/class-ai-translator-admin.php:382 #: includes/class-ai-translator-admin.php:334
msgid "Translation fields" msgid "Translation fields"
msgstr "Campos a traducir" msgstr "Campos a traducir"
#: includes/class-ai-translator-admin.php:230 #: includes/class-ai-translator-admin.php:218
#: includes/class-ai-translator-admin.php:386 #: includes/class-ai-translator-admin.php:338
#: includes/class-ai-translator-editor-ui.php:565 #: includes/class-ai-translator-editor-ui.php:453
msgid "Translate title" msgid "Translate title"
msgstr "Traducir título" msgstr "Traducir título"
#: includes/class-ai-translator-admin.php:235 #: includes/class-ai-translator-admin.php:223
#: includes/class-ai-translator-admin.php:391 #: includes/class-ai-translator-admin.php:343
#: includes/class-ai-translator-editor-ui.php:566 #: includes/class-ai-translator-editor-ui.php:454
msgid "Translate content" msgid "Translate content"
msgstr "Traducir contenido" msgstr "Traducir contenido"
#: includes/class-ai-translator-admin.php:240 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:396 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-editor-ui.php:567 #: includes/class-ai-translator-admin.php:239
msgid "Translate excerpt"
msgstr "Traducir extracto"
#. translators: 1: title default, 2: content default, 3: excerpt default.
#: includes/class-ai-translator-admin.php:248
#, php-format
msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s."
msgstr ""
"Valores predeterminados de la red: título %1$s, contenido %2$s, extracto "
"%3$s."
#: includes/class-ai-translator-admin.php:249
#: includes/class-ai-translator-admin.php:250
#: includes/class-ai-translator-admin.php:251
msgid "enabled" msgid "enabled"
msgstr "activado" msgstr "activado"
#: includes/class-ai-translator-admin.php:249 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:250 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-admin.php:251 #: includes/class-ai-translator-admin.php:239
msgid "disabled" msgid "disabled"
msgstr "desactivado" msgstr "desactivado"
#: includes/class-ai-translator-admin.php:262
#: includes/class-ai-translator-admin.php:408
msgid "Request timeout"
msgstr "Tiempo máximo de respuesta"
#: includes/class-ai-translator-admin.php:275
#: includes/class-ai-translator-admin.php:421
msgid "seconds"
msgstr "segundos"
#. translators: %d: PHP max_execution_time in seconds.
#: includes/class-ai-translator-admin.php:283
#: includes/class-ai-translator-admin.php:429
#, php-format
msgid ""
"Maximum time the server waits for an AI response. PHP max_execution_time is "
"%d s — values above this have no effect."
msgstr ""
"Tiempo máximo que el servidor espera una respuesta de la IA. El "
"max_execution_time de PHP es de %d s — los valores superiores no tienen "
"efecto."
#: includes/class-ai-translator-admin.php:287
#: includes/class-ai-translator-admin.php:433
msgid ""
"Maximum time the server waits for an AI response. PHP max_execution_time is "
"unlimited."
msgstr ""
"Tiempo máximo que el servidor espera una respuesta de la IA. El "
"max_execution_time de PHP es ilimitado."
#: includes/class-ai-translator-admin.php:296 #: includes/class-ai-translator-admin.php:296
#: includes/class-ai-translator-admin.php:299
#: includes/class-ai-translator-admin.php:442
#: includes/class-ai-translator-admin.php:445
msgid "MultilingualPress"
msgstr "MultilingualPress"
#: includes/class-ai-translator-admin.php:303
#: includes/class-ai-translator-admin.php:449
msgid "Auto-translate new connected posts"
msgstr "Traducir automáticamente las entradas conectadas nuevas"
#: includes/class-ai-translator-admin.php:307
#: includes/class-ai-translator-admin.php:453
msgid ""
"When MultilingualPress creates a new connected post, automatically translate "
"its enabled fields into the target site's language. The translation runs "
"synchronously during save."
msgstr ""
"Cuando MultilingualPress crea una entrada conectada nueva, traduce "
"automáticamente los campos activados al idioma del sitio de destino. La "
"traducción se ejecuta de forma síncrona al guardar."
#: includes/class-ai-translator-admin.php:342
msgid "AI Translator Network Settings" msgid "AI Translator Network Settings"
msgstr "Ajustes de red de AI Translator" msgstr "Ajustes de red de AI Translator"
#: includes/class-ai-translator-admin.php:348 #: includes/class-ai-translator-admin.php:300
msgid "Network settings saved." msgid "Network settings saved."
msgstr "Ajustes de red guardados." msgstr "Ajustes de red guardados."
#: includes/class-ai-translator-admin.php:358 #: includes/class-ai-translator-admin.php:310
#: includes/class-ai-translator-admin.php:361 #: includes/class-ai-translator-admin.php:313
msgid "Configuration mode" msgid "Configuration mode"
msgstr "Modo de configuración" msgstr "Modo de configuración"
#: includes/class-ai-translator-admin.php:365 #: includes/class-ai-translator-admin.php:317
msgid "Global configuration: a single setting applies to every site." msgid "Global configuration: a single setting applies to every site."
msgstr "Configuración global: un único ajuste se aplica a todos los sitios." msgstr "Configuración global: un único ajuste se aplica a todos los sitios."
#: includes/class-ai-translator-admin.php:370 #: includes/class-ai-translator-admin.php:322
msgid "Per-site configuration: each site can override these defaults." msgid "Per-site configuration: each site can override these defaults."
msgstr "" msgstr "Configuración por sitio: cada sitio puede sobrescribir estos valores por defecto."
"Configuración por sitio: cada sitio puede sobrescribir estos valores por "
"defecto."
#: includes/class-ai-translator-admin.php:400 #: includes/class-ai-translator-admin.php:352
msgid "" msgid "In global mode this is the configuration for the whole network. In per-site mode these values are used as defaults for sites that have not been configured individually."
"In global mode this is the configuration for the whole network. In per-site " msgstr "En modo global esta es la configuración para toda la red. En modo por sitio estos valores se usan como predeterminados para los sitios que no se hayan configurado individualmente."
"mode these values are used as defaults for sites that have not been "
"configured individually."
msgstr ""
"En modo global esta es la configuración para toda la red. En modo por sitio "
"estos valores se usan como predeterminados para los sitios que no se hayan "
"configurado individualmente."
#: includes/class-ai-translator-admin.php:479 #: includes/class-ai-translator-admin.php:397
#: includes/class-ai-translator-admin.php:511 #: includes/class-ai-translator-admin.php:429
msgid "You do not have permission to perform this action." msgid "You do not have permission to perform this action."
msgstr "No tienes permiso para realizar esta acción." msgstr "No tienes permiso para realizar esta acción."
#: includes/class-ai-translator-admin.php:555 #: includes/class-ai-translator-admin.php:473
msgid "Recommended models" msgid "Recommended models"
msgstr "Modelos recomendados" msgstr "Modelos recomendados"
#: includes/class-ai-translator-admin.php:558 #: includes/class-ai-translator-admin.php:476
msgid "" msgid "This plugin does not call AI providers directly. Configure your preferred provider in the WordPress AI plugin settings. The table below is a guide to help you pick a model based on your translation use case."
"This plugin does not call AI providers directly. Configure your preferred " msgstr "Este plugin no llama directamente a los proveedores de IA. Configura tu proveedor preferido en los ajustes del plugin WordPress AI. La tabla siguiente es una guía para ayudarte a elegir un modelo según tu caso de uso de traducción."
"provider in the WordPress AI plugin settings. The table below is a guide to "
"help you pick a model based on your translation use case."
msgstr ""
"Este plugin no llama directamente a los proveedores de IA. Configura tu "
"proveedor preferido en los ajustes del plugin WordPress AI. La tabla "
"siguiente es una guía para ayudarte a elegir un modelo según tu caso de uso "
"de traducción."
#: includes/class-ai-translator-admin.php:564 #: includes/class-ai-translator-admin.php:482
msgid "Use case" msgid "Use case"
msgstr "Caso de uso" msgstr "Caso de uso"
#: includes/class-ai-translator-admin.php:565 #: includes/class-ai-translator-admin.php:483
msgid "Recommended model" msgid "Recommended model"
msgstr "Modelo recomendado" msgstr "Modelo recomendado"
#: includes/class-ai-translator-admin.php:566 #: includes/class-ai-translator-admin.php:484
msgid "Why" msgid "Why"
msgstr "Por qué" msgstr "Por qué"
#: includes/class-ai-translator-admin.php:581 #: includes/class-ai-translator-admin.php:499
msgid "" msgid "These recommendations are based on public benchmarks and community feedback as of the plugin release date. They may change as providers update their models."
"These recommendations are based on public benchmarks and community feedback " msgstr "Estas recomendaciones se basan en benchmarks públicos y comentarios de la comunidad en la fecha de publicación del plugin. Pueden cambiar a medida que los proveedores actualicen sus modelos."
"as of the plugin release date. They may change as providers update their "
"models."
msgstr ""
"Estas recomendaciones se basan en benchmarks públicos y comentarios de la "
"comunidad en la fecha de publicación del plugin. Pueden cambiar a medida que "
"los proveedores actualicen sus modelos."
#: includes/class-ai-translator-admin.php:596 #: includes/class-ai-translator-admin.php:514
msgid "European languages (ES, CA, FR, DE, IT, PT)" msgid "European languages (ES, CA, FR, DE, IT, PT)"
msgstr "Idiomas europeos (ES, CA, FR, DE, IT, PT)" msgstr "Idiomas europeos (ES, CA, FR, DE, IT, PT)"
#: includes/class-ai-translator-admin.php:597 #: includes/class-ai-translator-admin.php:515
msgid "DeepL API Pro" msgid "DeepL API Pro"
msgstr "DeepL API Pro" msgstr "DeepL API Pro"
#: includes/class-ai-translator-admin.php:598 #: includes/class-ai-translator-admin.php:516
msgid "" msgid "Best fluency and naturalness (92/100 in benchmarks). Formality control and custom glossaries."
"Best fluency and naturalness (92/100 in benchmarks). Formality control and " msgstr "La mejor fluidez y naturalidad (92/100 en benchmarks). Control de formalidad y glosarios personalizados."
"custom glossaries."
msgstr ""
"La mejor fluidez y naturalidad (92/100 en benchmarks). Control de formalidad "
"y glosarios personalizados."
#: includes/class-ai-translator-admin.php:601 #: includes/class-ai-translator-admin.php:519
msgid "Asian languages (ZH, JA, KO)" msgid "Asian languages (ZH, JA, KO)"
msgstr "Idiomas asiáticos (ZH, JA, KO)" msgstr "Idiomas asiáticos (ZH, JA, KO)"
#: includes/class-ai-translator-admin.php:602 #: includes/class-ai-translator-admin.php:520
msgid "GPT-4o / GPT-5 or Claude Sonnet 4" msgid "GPT-4o / GPT-5 or Claude Sonnet 4"
msgstr "GPT-4o / GPT-5 o Claude Sonnet 4" msgstr "GPT-4o / GPT-5 o Claude Sonnet 4"
#: includes/class-ai-translator-admin.php:603 #: includes/class-ai-translator-admin.php:521
msgid "" msgid "Better handling of implicit subjects, honorifics, and cultural references. DeepL falls behind here."
"Better handling of implicit subjects, honorifics, and cultural references. " msgstr "Mejor manejo de sujetos implícitos, honoríficos y referencias culturales. DeepL queda por detrás aquí."
"DeepL falls behind here."
msgstr ""
"Mejor manejo de sujetos implícitos, honoríficos y referencias culturales. "
"DeepL queda por detrás aquí."
#: includes/class-ai-translator-admin.php:606 #: includes/class-ai-translator-admin.php:524
msgid "Marketing / brand tone" msgid "Marketing / brand tone"
msgstr "Marketing / tono de marca" msgstr "Marketing / tono de marca"
#: includes/class-ai-translator-admin.php:607 #: includes/class-ai-translator-admin.php:525
msgid "Claude Sonnet 4 / Opus 4" msgid "Claude Sonnet 4 / Opus 4"
msgstr "Claude Sonnet 4 / Opus 4" msgstr "Claude Sonnet 4 / Opus 4"
#: includes/class-ai-translator-admin.php:608 #: includes/class-ai-translator-admin.php:526
msgid "" msgid "Better preservation of tone, brand voice, and nuance. Ideal for creative copy."
"Better preservation of tone, brand voice, and nuance. Ideal for creative " msgstr "Preserva mejor el tono, la voz de marca y los matices. Ideal para copy creativo."
"copy."
msgstr ""
"Preserva mejor el tono, la voz de marca y los matices. Ideal para copy "
"creativo."
#: includes/class-ai-translator-admin.php:611 #: includes/class-ai-translator-admin.php:529
msgid "Technical documentation / code" msgid "Technical documentation / code"
msgstr "Documentación técnica / código" msgstr "Documentación técnica / código"
#: includes/class-ai-translator-admin.php:612 #: includes/class-ai-translator-admin.php:530
msgid "GPT-4o / GPT-5" msgid "GPT-4o / GPT-5"
msgstr "GPT-4o / GPT-5" msgstr "GPT-4o / GPT-5"
#: includes/class-ai-translator-admin.php:613 #: includes/class-ai-translator-admin.php:531
msgid "" msgid "Higher accuracy with variables, structured formats, and technical terminology."
"Higher accuracy with variables, structured formats, and technical " msgstr "Mayor precisión con variables, formatos estructurados y terminología técnica."
"terminology."
msgstr ""
"Mayor precisión con variables, formatos estructurados y terminología técnica."
#: includes/class-ai-translator-admin.php:616 #: includes/class-ai-translator-admin.php:534
msgid "Long documents (100+ pages)" msgid "Long documents (100+ pages)"
msgstr "Documentos largos (más de 100 páginas)" msgstr "Documentos largos (más de 100 páginas)"
#: includes/class-ai-translator-admin.php:617 #: includes/class-ai-translator-admin.php:535
msgid "Gemini 2.5 Pro" msgid "Gemini 2.5 Pro"
msgstr "Gemini 2.5 Pro" msgstr "Gemini 2.5 Pro"
#: includes/class-ai-translator-admin.php:618 #: includes/class-ai-translator-admin.php:536
msgid "" msgid "1M token context window. Maintains terminological consistency across long texts."
"1M token context window. Maintains terminological consistency across long " msgstr "Ventana de contexto de 1 millón de tokens. Mantiene la consistencia terminológica en textos extensos."
"texts."
msgstr ""
"Ventana de contexto de 1 millón de tokens. Mantiene la consistencia "
"terminológica en textos extensos."
#: includes/class-ai-translator-admin.php:621 #: includes/class-ai-translator-admin.php:539
msgid "High volume / low cost" msgid "High volume / low cost"
msgstr "Alto volumen / bajo coste" msgstr "Alto volumen / bajo coste"
#: includes/class-ai-translator-admin.php:622 #: includes/class-ai-translator-admin.php:540
msgid "DeepSeek-V3" msgid "DeepSeek-V3"
msgstr "DeepSeek-V3" msgstr "DeepSeek-V3"
#: includes/class-ai-translator-admin.php:623 #: includes/class-ai-translator-admin.php:541
msgid "" msgid "Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/GPT)."
"Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/" msgstr "Calidad comparable a GPT-5 a ~0,14 $/M tokens (entre 20 y 50 veces más barato que Claude/GPT)."
"GPT)."
msgstr ""
"Calidad comparable a GPT-5 a ~0,14 $/M tokens (entre 20 y 50 veces más "
"barato que Claude/GPT)."
#: includes/class-ai-translator-admin.php:626 #: includes/class-ai-translator-admin.php:544
msgid "Rare / indigenous languages" msgid "Rare / indigenous languages"
msgstr "Idiomas raros / indígenas" msgstr "Idiomas raros / indígenas"
#: includes/class-ai-translator-admin.php:627 #: includes/class-ai-translator-admin.php:545
msgid "Claude Sonnet or Taskade Translate (multi-model routing)" msgid "Claude Sonnet or Taskade Translate (multi-model routing)"
msgstr "Claude Sonnet o Taskade Translate (enrutado multimodelo)" msgstr "Claude Sonnet o Taskade Translate (enrutado multimodelo)"
#: includes/class-ai-translator-admin.php:628 #: includes/class-ai-translator-admin.php:546
msgid "Better coverage for uncommon language pairs." msgid "Better coverage for uncommon language pairs."
msgstr "Mejor cobertura en pares de idiomas poco comunes." msgstr "Mejor cobertura en pares de idiomas poco comunes."
#: includes/class-ai-translator-admin.php:631 #: includes/class-ai-translator-admin.php:549
msgid "Maximum coverage (133+ languages)" msgid "Maximum coverage (133+ languages)"
msgstr "Cobertura máxima (más de 133 idiomas)" msgstr "Cobertura máxima (más de 133 idiomas)"
#: includes/class-ai-translator-admin.php:632 #: includes/class-ai-translator-admin.php:550
msgid "Google Cloud Translation" msgid "Google Cloud Translation"
msgstr "Google Cloud Translation" msgstr "Google Cloud Translation"
#: includes/class-ai-translator-admin.php:633 #: includes/class-ai-translator-admin.php:551
msgid "" msgid "The most complete option, though with slightly lower quality on European languages."
"The most complete option, though with slightly lower quality on European " msgstr "La opción más completa, aunque con calidad ligeramente inferior en idiomas europeos."
"languages."
msgstr ""
"La opción más completa, aunque con calidad ligeramente inferior en idiomas "
"europeos."
#: includes/class-ai-translator-cli.php:120 #: includes/class-ai-translator-cli.php:120
msgid "The --locale flag is required." msgid "The --locale flag is required."
@ -378,37 +240,16 @@ msgstr "El parámetro --locale es obligatorio."
msgid "The --post-id and --post-type flags are mutually exclusive." msgid "The --post-id and --post-type flags are mutually exclusive."
msgstr "Los parámetros --post-id y --post-type son mutuamente excluyentes." msgstr "Los parámetros --post-id y --post-type son mutuamente excluyentes."
#: includes/class-ai-translator-cli.php:141
msgid "No user context. Pass --user=<id|login> so post updates carry an author and capability checks apply."
msgstr "Sin contexto de usuario. Pasa --user=<id|login> para que las actualizaciones de entradas tengan autor y se apliquen los controles de capacidades."
#. translators: %s: locale code. #. translators: %s: locale code.
#: includes/class-ai-translator-cli.php:133 #: includes/class-ai-translator-cli.php:133
#, php-format #, php-format
msgid "The locale %s is not installed on this site." msgid "The locale %s is not installed on this site."
msgstr "El idioma %s no está instalado en este sitio." msgstr "El idioma %s no está instalado en este sitio."
#: includes/class-ai-translator-cli.php:141
msgid ""
"No user context. Pass --user=<id|login> so post updates carry an author and "
"capability checks apply."
msgstr ""
"Sin contexto de usuario. Pasa --user=<id|login> para que las actualizaciones "
"de entradas tengan autor y se apliquen los controles de capacidades."
#: includes/class-ai-translator-cli.php:145
#: includes/class-ai-translator-editor-ui.php:427
#: includes/class-ai-translator-editor-ui.php:563
#: includes/class-ai-translator-translator.php:135
msgid "AI features are disabled for this WordPress installation."
msgstr ""
"Las funciones de IA están desactivadas para esta instalación de WordPress."
#: includes/class-ai-translator-cli.php:149
#: includes/class-ai-translator-translator.php:142
msgid ""
"No AI provider is configured for text generation. Open Settings → AI to set "
"one up."
msgstr ""
"No hay ningún proveedor de IA configurado para la generación de texto. Abre "
"Ajustes → IA para configurar uno."
#: includes/class-ai-translator-cli.php:155 #: includes/class-ai-translator-cli.php:155
msgid "No translation fields are enabled in the plugin settings." msgid "No translation fields are enabled in the plugin settings."
msgstr "No hay ningún campo de traducción activado en los ajustes del plugin." msgstr "No hay ningún campo de traducción activado en los ajustes del plugin."
@ -423,131 +264,169 @@ msgstr "Ninguna entrada coincide con los criterios indicados."
msgid "%1$d translated, %2$d failed (locale: %3$s)." msgid "%1$d translated, %2$d failed (locale: %3$s)."
msgstr "%1$d traducidas, %2$d con fallos (idioma: %3$s)." msgstr "%1$d traducidas, %2$d con fallos (idioma: %3$s)."
#: includes/class-ai-translator-editor-ui.php:229 #: includes/class-ai-translator-editor-ui.php:160
#: includes/class-ai-translator-editor-ui.php:298
msgid "Post not found."
msgstr "Entrada no encontrada."
#: includes/class-ai-translator-editor-ui.php:239
#: includes/class-ai-translator-editor-ui.php:307
msgid "The selected language is not installed on this site."
msgstr "El idioma seleccionado no está instalado en este sitio."
#: includes/class-ai-translator-editor-ui.php:268
msgid "Sorry, you are not allowed to edit this post." msgid "Sorry, you are not allowed to edit this post."
msgstr "Lo sentimos, no tienes permiso para editar esta entrada." msgstr "Lo sentimos, no tienes permiso para editar esta entrada."
#: includes/class-ai-translator-editor-ui.php:329 #: includes/class-ai-translator-editor-ui.php:190
msgid "" msgid "Post not found."
"No translatable fields were selected, or the requested fields are disabled " msgstr "Entrada no encontrada."
"in the settings."
msgstr ""
"No se ha seleccionado ningún campo traducible, o los campos solicitados "
"están desactivados en los ajustes."
#: includes/class-ai-translator-editor-ui.php:429 #: includes/class-ai-translator-editor-ui.php:199
#: includes/class-ai-translator-editor-ui.php:562 msgid "The selected language is not installed on this site."
msgstr "El idioma seleccionado no está instalado en este sitio."
#: includes/class-ai-translator-editor-ui.php:221
msgid "No translatable fields were selected, or the requested fields are disabled in the settings."
msgstr "No se ha seleccionado ningún campo traducible, o los campos solicitados están desactivados en los ajustes."
#: includes/class-ai-translator-editor-ui.php:321
#: includes/class-ai-translator-editor-ui.php:450
msgid "No translation fields are enabled in settings." msgid "No translation fields are enabled in settings."
msgstr "No hay ningún campo de traducción activado en los ajustes." msgstr "No hay ningún campo de traducción activado en los ajustes."
#: includes/class-ai-translator-editor-ui.php:431 #: includes/class-ai-translator-editor-ui.php:323
#: includes/class-ai-translator-editor-ui.php:561 #: includes/class-ai-translator-editor-ui.php:449
msgid "No languages are installed on this site." msgid "No languages are installed on this site."
msgstr "No hay ningún idioma instalado en este sitio." msgstr "No hay ningún idioma instalado en este sitio."
#: includes/class-ai-translator-editor-ui.php:434 #: includes/class-ai-translator-editor-ui.php:326
#: includes/class-ai-translator-editor-ui.php:557 #: includes/class-ai-translator-editor-ui.php:445
msgid "Target language" msgid "Target language"
msgstr "Idioma de destino" msgstr "Idioma de destino"
#: includes/class-ai-translator-editor-ui.php:444 #: includes/class-ai-translator-editor-ui.php:336
#: includes/class-ai-translator-editor-ui.php:553 #: includes/class-ai-translator-editor-ui.php:443
msgid "Translate" msgid "Translate"
msgstr "Traducir" msgstr "Traducir"
#: includes/class-ai-translator-editor-ui.php:449 #: includes/class-ai-translator-editor-ui.php:341
msgid "" msgid "Save the post before translating to ensure the latest content is used. The translation replaces the current title and/or content."
"Save the post before translating to ensure the latest content is used. The " msgstr "Guarda la entrada antes de traducir para que se use la versión más reciente. La traducción reemplaza el título y/o el contenido actuales."
"translation replaces the current title and/or content."
msgstr ""
"Guarda la entrada antes de traducir para que se use la versión más reciente. "
"La traducción reemplaza el título y/o el contenido actuales."
#: includes/class-ai-translator-editor-ui.php:554 #: includes/class-ai-translator-editor-ui.php:444
msgid "Translating…" msgid "Translating…"
msgstr "Traduciendo…" msgstr "Traduciendo…"
#. translators: 1: number of chunks translated so far, 2: total number of chunks. #: includes/class-ai-translator-editor-ui.php:447
#: includes/class-ai-translator-editor-ui.php:556
msgid "Translating… ({done}/{total})"
msgstr "Traduciendo… ({done}/{total})"
#: includes/class-ai-translator-editor-ui.php:559
msgid "Translation applied. Review and save the post." msgid "Translation applied. Review and save the post."
msgstr "Traducción aplicada. Revisa y guarda la entrada." msgstr "Traducción aplicada. Revisa y guarda la entrada."
#: includes/class-ai-translator-editor-ui.php:560 #: includes/class-ai-translator-editor-ui.php:448
msgid "Translation failed." msgid "Translation failed."
msgstr "La traducción ha fallado." msgstr "La traducción ha fallado."
#: includes/class-ai-translator-editor-ui.php:564 #: includes/class-ai-translator-editor-ui.php:452
msgid "" msgid "You have unsaved changes. Save the post before translating to ensure the latest content is used."
"You have unsaved changes. Save the post before translating to ensure the " msgstr "Tienes cambios sin guardar. Guarda la entrada antes de traducir para que se use la versión más reciente."
"latest content is used."
msgstr ""
"Tienes cambios sin guardar. Guarda la entrada antes de traducir para que se "
"use la versión más reciente."
#: includes/class-ai-translator-manager-notice.php:162 #: includes/class-ai-translator-translator.php:102
#: includes/class-ai-translator-manager-notice.php:185
msgid ""
"To get updates for the ROBOTSTXT plugins, the plugin below must be installed "
"and active:"
msgstr ""
"Para recibir actualizaciones de los plugins de ROBOTSTXT, el plugin "
"siguiente debe estar instalado y activo:"
#: includes/class-ai-translator-manager-notice.php:164
#: includes/class-ai-translator-manager-notice.php:187
msgid "Manager (by ROBOTSTXT)"
msgstr "Manager (by ROBOTSTXT)"
#: includes/class-ai-translator-manager-notice.php:166
msgid "Dismiss this notice"
msgstr "Descartar este aviso"
#: includes/class-ai-translator-translator.php:151
msgid "The target language is not installed on this site." msgid "The target language is not installed on this site."
msgstr "El idioma de destino no está instalado en este sitio." msgstr "El idioma de destino no está instalado en este sitio."
#. translators: %s: target language name. #. translators: %s: target language name.
#: includes/class-ai-translator-translator.php:157 #: includes/class-ai-translator-translator.php:108
#, php-format #, php-format
msgid "" msgid "You are a professional translator. Translate the user message into %s. Preserve any HTML, shortcodes, line breaks, and Markdown exactly as they appear. Return only the translated text, without explanations, prefaces, or quotation marks."
"You are a professional translator. Translate the user message into %s. " msgstr "Eres un traductor profesional. Traduce el mensaje del usuario al %s. Preserva el HTML, los shortcodes, los saltos de línea y el Markdown exactamente como aparecen. Devuelve solo el texto traducido, sin explicaciones, prefacios ni comillas."
"Preserve any HTML, shortcodes, line breaks, and Markdown exactly as they "
"appear. Return only the translated text, without explanations, prefaces, or "
"quotation marks."
msgstr ""
"Eres un traductor profesional. Traduce el mensaje del usuario al %s. "
"Preserva el HTML, los shortcodes, los saltos de línea y el Markdown "
"exactamente como aparecen. Devuelve solo el texto traducido, sin "
"explicaciones, prefacios ni comillas."
#: includes/class-ai-translator-translator.php:186 #: includes/class-ai-translator-translator.php:129
msgid "The AI service returned an unexpected response." msgid "The AI service returned an unexpected response."
msgstr "El servicio de IA ha devuelto una respuesta inesperada." msgstr "El servicio de IA ha devuelto una respuesta inesperada."
#. translators: %s: Link to the WordPress AI settings page. #: class-robotstxt-updater.php:456
#: robotstxt-ai-translator.php:145 msgid "You do not have sufficient permissions to access this page."
#, php-format msgstr "No tienes permisos suficientes para acceder a esta página."
msgid ""
"AI Translator (by ROBOTSTXT) requires a configured AI provider for text "
"generation. Open %s to set one up."
msgstr ""
"AI Translator (by ROBOTSTXT) requiere un proveedor de IA configurado para la "
"generación de texto. Abre %s para configurar uno."
#: robotstxt-ai-translator.php:146 #. Plugin URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator"
msgstr ""
#. Description of the plugin
#: robotstxt-ai-translator.php
msgid "Translate post titles and content from the editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration."
msgstr ""
#. Author URI of the plugin
#: robotstxt-ai-translator.php
msgid "https://www.robotstxt.es/"
msgstr ""
#: class-robotstxt-updater.php:452
msgid "Security check failed."
msgstr "Error de verificación de seguridad."
#: includes/class-ai-translator-admin.php:228
#: includes/class-ai-translator-admin.php:348
#: includes/class-ai-translator-editor-ui.php:455
msgid "Translate excerpt"
msgstr "Traducir extracto"
#. translators: 1: title default, 2: content default, 3: excerpt default.
#: includes/class-ai-translator-admin.php:236
#, php-format
msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s."
msgstr "Valores predeterminados de la red: título %1$s, contenido %2$s, extracto %3$s."
#: includes/class-ai-translator-admin.php:250
#: includes/class-ai-translator-admin.php:253
#: includes/class-ai-translator-admin.php:360
#: includes/class-ai-translator-admin.php:363
msgid "MultilingualPress"
msgstr "MultilingualPress"
#: includes/class-ai-translator-admin.php:257
#: includes/class-ai-translator-admin.php:367
msgid "Auto-translate new connected posts"
msgstr "Traducir automáticamente las entradas conectadas nuevas"
#: includes/class-ai-translator-admin.php:261
#: includes/class-ai-translator-admin.php:371
msgid "When MultilingualPress creates a new connected post, automatically translate its enabled fields into the target site's language. The translation runs synchronously during save."
msgstr "Cuando MultilingualPress crea una entrada conectada nueva, traduce automáticamente los campos activados al idioma del sitio de destino. La traducción se ejecuta de forma síncrona al guardar."
#: includes/class-ai-translator-cli.php:145
#: includes/class-ai-translator-editor-ui.php:319
#: includes/class-ai-translator-editor-ui.php:451
#: includes/class-ai-translator-translator.php:86
msgid "AI features are disabled for this WordPress installation."
msgstr "Las funciones de IA están desactivadas para esta instalación de WordPress."
#: includes/class-ai-translator-cli.php:149
#: includes/class-ai-translator-translator.php:93
msgid "No AI provider is configured for text generation. Open Settings → AI to set one up."
msgstr "No hay ningún proveedor de IA configurado para la generación de texto. Abre Ajustes → IA para configurar uno."
#. translators: %s: Link to the WordPress AI settings page.
#: robotstxt-ai-translator.php:144
#, php-format
msgid "AI Translator (by ROBOTSTXT) requires a configured AI provider for text generation. Open %s to set one up."
msgstr "AI Translator (by ROBOTSTXT) requiere un proveedor de IA configurado para la generación de texto. Abre %s para configurar uno."
#: robotstxt-ai-translator.php:145
msgid "Settings → AI" msgid "Settings → AI"
msgstr "Ajustes → IA" msgstr "Ajustes → IA"
#: includes/class-ai-translator-admin.php
msgid "Request timeout"
msgstr "Tiempo máximo de respuesta"
#: includes/class-ai-translator-admin.php
msgid "seconds"
msgstr "segundos"
#. translators: %d: PHP max_execution_time in seconds.
#: includes/class-ai-translator-admin.php
#, php-format
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is %d s — values above this have no effect."
msgstr "Tiempo máximo que el servidor espera una respuesta de la IA. El max_execution_time de PHP es de %d s — los valores superiores no tienen efecto."
#: includes/class-ai-translator-admin.php
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is unlimited."
msgstr "Tiempo máximo que el servidor espera una respuesta de la IA. El max_execution_time de PHP es ilimitado."
#. translators: 1: number of chunks translated so far, 2: total number of chunks.
#: includes/class-ai-translator-editor-ui.php
msgid "Translating… ({done}/{total})"
msgstr "Traduciendo… ({done}/{total})"

View file

@ -2,14 +2,14 @@
# This file is distributed under the GPL-3.0-or-later. # This file is distributed under the GPL-3.0-or-later.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.3\n" "Project-Id-Version: AI Translator (by ROBOTSTXT) 1.2.0\n"
"Report-Msgid-Bugs-To: https://www.robotstxt.software/plugins/robotstxt-ai-translator/\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/robotstxt-ai-translator\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2026-08-24T11:03:38+00:00\n" "POT-Creation-Date: 2026-05-28T06:44:22+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.12.0\n" "X-Generator: WP-CLI 2.12.0\n"
"X-Domain: robotstxt-ai-translator\n" "X-Domain: robotstxt-ai-translator\n"
@ -21,7 +21,7 @@ msgstr ""
#. Plugin URI of the plugin #. Plugin URI of the plugin
#: robotstxt-ai-translator.php #: robotstxt-ai-translator.php
msgid "https://www.robotstxt.software/plugins/robotstxt-ai-translator/" msgid "https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator"
msgstr "" msgstr ""
#. Description of the plugin #. Description of the plugin
@ -36,265 +36,273 @@ msgstr ""
#. Author URI of the plugin #. Author URI of the plugin
#: robotstxt-ai-translator.php #: robotstxt-ai-translator.php
msgid "https://www.robotstxt.software/" msgid "https://www.robotstxt.es/"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:122 #: class-robotstxt-updater.php:452
#: includes/class-ai-translator-admin.php:123 msgid "Security check failed."
#: includes/class-ai-translator-admin.php:140 msgstr ""
#: includes/class-ai-translator-admin.php:141
#: class-robotstxt-updater.php:456
msgid "You do not have sufficient permissions to access this page."
msgstr ""
#: includes/class-ai-translator-admin.php:112
#: includes/class-ai-translator-admin.php:113
#: includes/class-ai-translator-admin.php:130
#: includes/class-ai-translator-admin.php:131
#: includes/class-ai-translator-editor-ui.php:402 #: includes/class-ai-translator-editor-ui.php:402
#: includes/class-ai-translator-editor-ui.php:558 #: includes/class-ai-translator-editor-ui.php:558
msgid "AI Translator" msgid "AI Translator"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:163 #: includes/class-ai-translator-admin.php:153
#: includes/class-ai-translator-admin.php:181 #: includes/class-ai-translator-admin.php:171
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:197 #: includes/class-ai-translator-admin.php:187
#: includes/class-ai-translator-admin.php:333 #: includes/class-ai-translator-admin.php:321
msgid "You do not have permission to access this page." msgid "You do not have permission to access this page."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:206 #: includes/class-ai-translator-admin.php:196
msgid "AI Translator Settings" msgid "AI Translator Settings"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:212 #: includes/class-ai-translator-admin.php:200
msgid "Settings saved." msgid "Settings saved."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:223 #: includes/class-ai-translator-admin.php:211
#: includes/class-ai-translator-admin.php:226 #: includes/class-ai-translator-admin.php:214
#: includes/class-ai-translator-admin.php:378 #: includes/class-ai-translator-admin.php:364
#: includes/class-ai-translator-admin.php:382 #: includes/class-ai-translator-admin.php:368
msgid "Translation fields" msgid "Translation fields"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:230 #: includes/class-ai-translator-admin.php:218
#: includes/class-ai-translator-admin.php:386 #: includes/class-ai-translator-admin.php:372
#: includes/class-ai-translator-editor-ui.php:565 #: includes/class-ai-translator-editor-ui.php:565
msgid "Translate title" msgid "Translate title"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:235 #: includes/class-ai-translator-admin.php:223
#: includes/class-ai-translator-admin.php:391 #: includes/class-ai-translator-admin.php:377
#: includes/class-ai-translator-editor-ui.php:566 #: includes/class-ai-translator-editor-ui.php:566
msgid "Translate content" msgid "Translate content"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:240 #: includes/class-ai-translator-admin.php:228
#: includes/class-ai-translator-admin.php:396 #: includes/class-ai-translator-admin.php:382
#: includes/class-ai-translator-editor-ui.php:567 #: includes/class-ai-translator-editor-ui.php:567
msgid "Translate excerpt" msgid "Translate excerpt"
msgstr "" msgstr ""
#. translators: 1: title default, 2: content default, 3: excerpt default. #. translators: 1: title default, 2: content default, 3: excerpt default.
#: includes/class-ai-translator-admin.php:248 #: includes/class-ai-translator-admin.php:236
#, php-format #, php-format
msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s." msgid "Network defaults: title %1$s, content %2$s, excerpt %3$s."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:249 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:250 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-admin.php:251 #: includes/class-ai-translator-admin.php:239
msgid "enabled" msgid "enabled"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:249 #: includes/class-ai-translator-admin.php:237
#: includes/class-ai-translator-admin.php:250 #: includes/class-ai-translator-admin.php:238
#: includes/class-ai-translator-admin.php:251 #: includes/class-ai-translator-admin.php:239
msgid "disabled" msgid "disabled"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:262 #: includes/class-ai-translator-admin.php:250
#: includes/class-ai-translator-admin.php:408 #: includes/class-ai-translator-admin.php:394
msgid "Request timeout" msgid "Request timeout"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:275 #: includes/class-ai-translator-admin.php:263
#: includes/class-ai-translator-admin.php:421 #: includes/class-ai-translator-admin.php:407
msgid "seconds" msgid "seconds"
msgstr "" msgstr ""
#. translators: %d: PHP max_execution_time in seconds. #. translators: %d: PHP max_execution_time in seconds.
#: includes/class-ai-translator-admin.php:283 #: includes/class-ai-translator-admin.php:271
#: includes/class-ai-translator-admin.php:429 #: includes/class-ai-translator-admin.php:415
#, php-format #, php-format
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is %d s — values above this have no effect." msgid "Maximum time the server waits for an AI response. PHP max_execution_time is %d s — values above this have no effect."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:287 #: includes/class-ai-translator-admin.php:275
#: includes/class-ai-translator-admin.php:433 #: includes/class-ai-translator-admin.php:419
msgid "Maximum time the server waits for an AI response. PHP max_execution_time is unlimited." msgid "Maximum time the server waits for an AI response. PHP max_execution_time is unlimited."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:296 #: includes/class-ai-translator-admin.php:284
#: includes/class-ai-translator-admin.php:299 #: includes/class-ai-translator-admin.php:287
#: includes/class-ai-translator-admin.php:442 #: includes/class-ai-translator-admin.php:428
#: includes/class-ai-translator-admin.php:445 #: includes/class-ai-translator-admin.php:431
msgid "MultilingualPress" msgid "MultilingualPress"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:303 #: includes/class-ai-translator-admin.php:291
#: includes/class-ai-translator-admin.php:449 #: includes/class-ai-translator-admin.php:435
msgid "Auto-translate new connected posts" msgid "Auto-translate new connected posts"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:307 #: includes/class-ai-translator-admin.php:295
#: includes/class-ai-translator-admin.php:453 #: includes/class-ai-translator-admin.php:439
msgid "When MultilingualPress creates a new connected post, automatically translate its enabled fields into the target site's language. The translation runs synchronously during save." msgid "When MultilingualPress creates a new connected post, automatically translate its enabled fields into the target site's language. The translation runs synchronously during save."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:342 #: includes/class-ai-translator-admin.php:330
msgid "AI Translator Network Settings" msgid "AI Translator Network Settings"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:348 #: includes/class-ai-translator-admin.php:334
msgid "Network settings saved." msgid "Network settings saved."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:358 #: includes/class-ai-translator-admin.php:344
#: includes/class-ai-translator-admin.php:361 #: includes/class-ai-translator-admin.php:347
msgid "Configuration mode" msgid "Configuration mode"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:365 #: includes/class-ai-translator-admin.php:351
msgid "Global configuration: a single setting applies to every site." msgid "Global configuration: a single setting applies to every site."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:370 #: includes/class-ai-translator-admin.php:356
msgid "Per-site configuration: each site can override these defaults." msgid "Per-site configuration: each site can override these defaults."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:400 #: includes/class-ai-translator-admin.php:386
msgid "In global mode this is the configuration for the whole network. In per-site mode these values are used as defaults for sites that have not been configured individually." msgid "In global mode this is the configuration for the whole network. In per-site mode these values are used as defaults for sites that have not been configured individually."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:479 #: includes/class-ai-translator-admin.php:465
#: includes/class-ai-translator-admin.php:511 #: includes/class-ai-translator-admin.php:497
msgid "You do not have permission to perform this action." msgid "You do not have permission to perform this action."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:555 #: includes/class-ai-translator-admin.php:541
msgid "Recommended models" msgid "Recommended models"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:558 #: includes/class-ai-translator-admin.php:544
msgid "This plugin does not call AI providers directly. Configure your preferred provider in the WordPress AI plugin settings. The table below is a guide to help you pick a model based on your translation use case." msgid "This plugin does not call AI providers directly. Configure your preferred provider in the WordPress AI plugin settings. The table below is a guide to help you pick a model based on your translation use case."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:564 #: includes/class-ai-translator-admin.php:550
msgid "Use case" msgid "Use case"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:565 #: includes/class-ai-translator-admin.php:551
msgid "Recommended model" msgid "Recommended model"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:566 #: includes/class-ai-translator-admin.php:552
msgid "Why" msgid "Why"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:581 #: includes/class-ai-translator-admin.php:567
msgid "These recommendations are based on public benchmarks and community feedback as of the plugin release date. They may change as providers update their models." msgid "These recommendations are based on public benchmarks and community feedback as of the plugin release date. They may change as providers update their models."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:596 #: includes/class-ai-translator-admin.php:582
msgid "European languages (ES, CA, FR, DE, IT, PT)" msgid "European languages (ES, CA, FR, DE, IT, PT)"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:597 #: includes/class-ai-translator-admin.php:583
msgid "DeepL API Pro" msgid "DeepL API Pro"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:598 #: includes/class-ai-translator-admin.php:584
msgid "Best fluency and naturalness (92/100 in benchmarks). Formality control and custom glossaries." msgid "Best fluency and naturalness (92/100 in benchmarks). Formality control and custom glossaries."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:601 #: includes/class-ai-translator-admin.php:587
msgid "Asian languages (ZH, JA, KO)" msgid "Asian languages (ZH, JA, KO)"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:602 #: includes/class-ai-translator-admin.php:588
msgid "GPT-4o / GPT-5 or Claude Sonnet 4" msgid "GPT-4o / GPT-5 or Claude Sonnet 4"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:603 #: includes/class-ai-translator-admin.php:589
msgid "Better handling of implicit subjects, honorifics, and cultural references. DeepL falls behind here." msgid "Better handling of implicit subjects, honorifics, and cultural references. DeepL falls behind here."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:606 #: includes/class-ai-translator-admin.php:592
msgid "Marketing / brand tone" msgid "Marketing / brand tone"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:607 #: includes/class-ai-translator-admin.php:593
msgid "Claude Sonnet 4 / Opus 4" msgid "Claude Sonnet 4 / Opus 4"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:608 #: includes/class-ai-translator-admin.php:594
msgid "Better preservation of tone, brand voice, and nuance. Ideal for creative copy." msgid "Better preservation of tone, brand voice, and nuance. Ideal for creative copy."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:611 #: includes/class-ai-translator-admin.php:597
msgid "Technical documentation / code" msgid "Technical documentation / code"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:612 #: includes/class-ai-translator-admin.php:598
msgid "GPT-4o / GPT-5" msgid "GPT-4o / GPT-5"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:613 #: includes/class-ai-translator-admin.php:599
msgid "Higher accuracy with variables, structured formats, and technical terminology." msgid "Higher accuracy with variables, structured formats, and technical terminology."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:616 #: includes/class-ai-translator-admin.php:602
msgid "Long documents (100+ pages)" msgid "Long documents (100+ pages)"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:617 #: includes/class-ai-translator-admin.php:603
msgid "Gemini 2.5 Pro" msgid "Gemini 2.5 Pro"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:618 #: includes/class-ai-translator-admin.php:604
msgid "1M token context window. Maintains terminological consistency across long texts." msgid "1M token context window. Maintains terminological consistency across long texts."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:621 #: includes/class-ai-translator-admin.php:607
msgid "High volume / low cost" msgid "High volume / low cost"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:622 #: includes/class-ai-translator-admin.php:608
msgid "DeepSeek-V3" msgid "DeepSeek-V3"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:623 #: includes/class-ai-translator-admin.php:609
msgid "Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/GPT)." msgid "Quality comparable to GPT-5 at ~$0.14/M tokens (20-50x cheaper than Claude/GPT)."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:626 #: includes/class-ai-translator-admin.php:612
msgid "Rare / indigenous languages" msgid "Rare / indigenous languages"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:627 #: includes/class-ai-translator-admin.php:613
msgid "Claude Sonnet or Taskade Translate (multi-model routing)" msgid "Claude Sonnet or Taskade Translate (multi-model routing)"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:628 #: includes/class-ai-translator-admin.php:614
msgid "Better coverage for uncommon language pairs." msgid "Better coverage for uncommon language pairs."
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:631 #: includes/class-ai-translator-admin.php:617
msgid "Maximum coverage (133+ languages)" msgid "Maximum coverage (133+ languages)"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:632 #: includes/class-ai-translator-admin.php:618
msgid "Google Cloud Translation" msgid "Google Cloud Translation"
msgstr "" msgstr ""
#: includes/class-ai-translator-admin.php:633 #: includes/class-ai-translator-admin.php:619
msgid "The most complete option, though with slightly lower quality on European languages." msgid "The most complete option, though with slightly lower quality on European languages."
msgstr "" msgstr ""
@ -405,20 +413,6 @@ msgstr ""
msgid "You have unsaved changes. Save the post before translating to ensure the latest content is used." msgid "You have unsaved changes. Save the post before translating to ensure the latest content is used."
msgstr "" msgstr ""
#: includes/class-ai-translator-manager-notice.php:162
#: includes/class-ai-translator-manager-notice.php:185
msgid "To get updates for the ROBOTSTXT plugins, the plugin below must be installed and active:"
msgstr ""
#: includes/class-ai-translator-manager-notice.php:164
#: includes/class-ai-translator-manager-notice.php:187
msgid "Manager (by ROBOTSTXT)"
msgstr ""
#: includes/class-ai-translator-manager-notice.php:166
msgid "Dismiss this notice"
msgstr ""
#: includes/class-ai-translator-translator.php:151 #: includes/class-ai-translator-translator.php:151
msgid "The target language is not installed on this site." msgid "The target language is not installed on this site."
msgstr "" msgstr ""
@ -434,11 +428,11 @@ msgid "The AI service returned an unexpected response."
msgstr "" msgstr ""
#. translators: %s: Link to the WordPress AI settings page. #. translators: %s: Link to the WordPress AI settings page.
#: robotstxt-ai-translator.php:145 #: robotstxt-ai-translator.php:144
#, php-format #, php-format
msgid "AI Translator (by ROBOTSTXT) requires a configured AI provider for text generation. Open %s to set one up." msgid "AI Translator (by ROBOTSTXT) requires a configured AI provider for text generation. Open %s to set one up."
msgstr "" msgstr ""
#: robotstxt-ai-translator.php:146 #: robotstxt-ai-translator.php:145
msgid "Settings → AI" msgid "Settings → AI"
msgstr "" msgstr ""

View file

@ -3,8 +3,8 @@ Contributors: robotstxt, javiercasares
Tags: ai, translation, multilingual, multisite, editor Tags: ai, translation, multilingual, multisite, editor
Requires at least: 7.0 Requires at least: 7.0
Tested up to: 7.1 Tested up to: 7.1
Requires PHP: 5.6 Requires PHP: 7.4
Stable tag: 1.2.3 Stable tag: 1.2.1
License: GPL-3.0-or-later License: GPL-3.0-or-later
License URI: https://www.gnu.org/licenses/gpl-3.0.txt License URI: https://www.gnu.org/licenses/gpl-3.0.txt
@ -109,7 +109,7 @@ The endpoint reads the **saved** title and content from the database, not from t
= Requirements = = Requirements =
* WordPress 7.0 or higher (the `wp_ai_client_prompt()` function is part of WordPress core since 7.0). * WordPress 7.0 or higher (the `wp_ai_client_prompt()` function is part of WordPress core since 7.0).
* PHP 5.6 or higher. * PHP 7.4 or higher.
* At least one AI provider configured in Settings → AI. The plugin works with any provider registered through the WordPress AI client — no specific AI plugin is required. * At least one AI provider configured in Settings → AI. The plugin works with any provider registered through the WordPress AI client — no specific AI plugin is required.
= Manual download = = Manual download =
@ -135,31 +135,37 @@ The plugin reads the post title and content from the database, not from the edit
== Compatibility == == Compatibility ==
* WordPress: 7.0 - 7.1 * WordPress: 7.0 - 7.1
* PHP: 5.6 - 8.5 * PHP: 7.4 - 8.5
* WP-CLI: 2.12 or newer * WP-CLI: 2.12 or newer
== Changelog == == Changelog ==
Only the 3 last versions. The full changelog will be at changelog.txt
= 1.2.3 =
* Manager (by ROBOTSTXT) detection now uses the ecosystem presence constant `ROBOTSTXT_MANAGER_NOTICED` (Manager 1.6.2+) instead of scanning the plugin list, falling back to the plugin-list scan for older Manager versions.
= 1.2.2 =
* Added a dismissible admin notice on the Plugins list screens recommending Manager (by ROBOTSTXT) when it is not installed and active, plus a persistent warning on the plugin settings pages. Updates for the ROBOTSTXT plugins are delivered through Manager.
* Removed the bundled JSON updater (`class-robotstxt-updater.php` and `update.json`). Plugin updates are now handled by Manager.
* Changed the Plugin URI and Update URI to `https://www.robotstxt.software/plugins/robotstxt-ai-translator/`.
* Lowered the minimum PHP version from 7.4 to 5.6 (verified with PHPCompatibility 5.6-8.5). WordPress 7.0+ remains the minimum WordPress version because the plugin uses the native WordPress AI client.
= 1.2.1 = = 1.2.1 =
* Confirmed compatibility with WordPress 7.1. No functional changes. * Confirmed compatibility with WordPress 7.1. No functional changes.
= 1.2.0 =
* Added configurable "Request timeout" setting (default 60 s, minimum 30 s, maximum 300 s) in site and network admin pages.
* Added parallel chunked content translation: long posts are split at Gutenberg block or paragraph boundaries and all chunks are sent to the AI concurrently, eliminating timeout errors on lengthy content.
* Added real-time progress indicator on the Translate button: "Translating… (2/5)" as each chunk resolves.
* Added new REST endpoint `POST /wp-json/ai-translator/v1/translate-text` for raw-text translation; used internally by the chunked content path.
* Changed: content translation now reads from the current editor state (unsaved changes included); title and excerpt continue to read from the saved post.
= 1.1.0 =
* Added excerpt field (`post_excerpt`) as a translatable field, with a dedicated settings toggle.
* Added MultilingualPress integration: when MLP creates a new connected post, the plugin automatically translates the enabled fields into the target site's language (opt-in, disabled by default).
* Removed `Requires Plugins: ai` header — `wp_ai_client_prompt()` is a native WordPress 7.0 function; the plugin now works with any AI provider configured through WordPress core.
* Admin notice now shows when no AI provider is configured for text generation (instead of checking for a function that always exists in WP 7.0+).
= 1.0.0 =
* Initial release. Translation panel for block and classic editors, REST endpoint, WP-CLI command, single-site and Multisite (global / per-site) configuration modes.
= Previous versions = = Previous versions =
If you want to see the full changelog, visit the [changelog](https://www.robotstxt.software/plugins/robotstxt-ai-translator/) page. If you want to see the full changelog, visit the [changelog.txt](https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator/raw/branch/main/changelog.txt) file.
== Compliance == == Compliance ==

View file

@ -1,18 +1,18 @@
<?php <?php
/** /**
* Plugin Name: AI Translator (by ROBOTSTXT) * Plugin Name: AI Translator (by ROBOTSTXT)
* Plugin URI: https://www.robotstxt.software/plugins/robotstxt-ai-translator/ * Plugin URI: https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator
* Update URI: https://www.robotstxt.software/plugins/robotstxt-ai-translator/ * Gitea Plugin URI: ROBOTSTXT/robotstxt-ai-translator
* Description: Translate post titles and content from the editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration. * Description: Translate post titles and content from the editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration.
* Version: 1.2.3 * Version: 1.2.1
* Author: ROBOTSTXT * Author: ROBOTSTXT
* Author URI: https://www.robotstxt.software/ * Author URI: https://www.robotstxt.es/
* License: GPL-3.0-or-later * License: GPL-3.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-3.0.txt * License URI: https://www.gnu.org/licenses/gpl-3.0.txt
* Text Domain: robotstxt-ai-translator * Text Domain: robotstxt-ai-translator
* Domain Path: /languages * Domain Path: /languages
* Requires at least: 7.0 * Requires at least: 7.0
* Requires PHP: 5.6 * Requires PHP: 7.4
* Network: true * Network: true
* *
* @package ROBOTSTXT\AI_Translator * @package ROBOTSTXT\AI_Translator
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
/** /**
* Plugin version. * Plugin version.
*/ */
define( 'AI_TRANSLATOR_VERSION', '1.2.3' ); define( 'AI_TRANSLATOR_VERSION', '1.2.1' );
/** /**
* Main plugin file path. * Main plugin file path.
@ -56,7 +56,7 @@ require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-settings.php';
require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-translator.php'; require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-translator.php';
require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-admin.php'; require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-admin.php';
require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-editor-ui.php'; require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-editor-ui.php';
require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-manager-notice.php'; require_once AI_TRANSLATOR_DIR . 'class-robotstxt-updater.php';
if ( class_exists( '\Inpsyde\MultilingualPress\TranslationUi\Post\MetaboxAction' ) ) { if ( class_exists( '\Inpsyde\MultilingualPress\TranslationUi\Post\MetaboxAction' ) ) {
require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-mlp-integration.php'; require_once AI_TRANSLATOR_DIR . 'includes/class-ai-translator-mlp-integration.php';
@ -95,8 +95,7 @@ add_action( 'init', 'ai_translator_load_textdomain' );
function ai_translator_bootstrap() { function ai_translator_bootstrap() {
$settings = new AI_Translator_Settings(); $settings = new AI_Translator_Settings();
$translator = new AI_Translator_Translator( $settings ); $translator = new AI_Translator_Translator( $settings );
$manager_notice = new AI_Translator_Manager_Notice(); $admin = new AI_Translator_Admin( $settings );
$admin = new AI_Translator_Admin( $settings, $manager_notice );
$editor_ui = new AI_Translator_Editor_UI( $settings, $translator ); $editor_ui = new AI_Translator_Editor_UI( $settings, $translator );
$admin->register(); $admin->register();
@ -112,7 +111,7 @@ function ai_translator_bootstrap() {
$mlp->register(); $mlp->register();
} }
$manager_notice->register(); Robotstxt_Updater::init( AI_TRANSLATOR_FILE );
} }
add_action( 'plugins_loaded', 'ai_translator_bootstrap' ); add_action( 'plugins_loaded', 'ai_translator_bootstrap' );

27
update.json Normal file
View file

@ -0,0 +1,27 @@
{
"name": "AI Translator (by ROBOTSTXT)",
"slug": "robotstxt-ai-translator",
"version": "1.2.1",
"download_url": "https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator/releases/download/1.2.1/robotstxt-ai-translator-1.2.1.zip",
"requires": "7.0",
"requires_php": "7.4",
"tested": "7.1",
"last_updated": "2026-08-07",
"author": "ROBOTSTXT",
"author_profile": "https://www.robotstxt.es/",
"homepage": "https://git.robotstxt.es/ROBOTSTXT/robotstxt-ai-translator",
"description": "Translate post titles and content from the WordPress editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration.",
"changelog": "<h3>1.2.1 - 2026-08-07</h3><ul><li><strong>Changed:</strong> Confirmed compatibility with WordPress 7.1. No functional changes.</li></ul><h3>1.2.0 - 2026-05-26</h3><ul><li><strong>Added:</strong> Configurable request timeout — new \"Request timeout\" setting (default 60 s, min 30 s, max 300 s) controls how long the server waits for an AI response before timing out.</li><li><strong>Added:</strong> Parallel chunked content translation — long post content is automatically split at block (Gutenberg) or paragraph (Classic editor) boundaries and translated in parallel, eliminating timeout errors on lengthy posts.</li><li><strong>Added:</strong> Progress indicator — the Translate button shows \"Translating… (2/5)\" while chunks are in flight.</li><li><strong>Added:</strong> New REST endpoint POST /wp-json/ai-translator/v1/translate-text for raw-text translation; used internally by the chunked content path.</li></ul><h3>1.1.0 - 2026-05-25</h3><ul><li><strong>Added:</strong> Excerpt translation — post_excerpt is now a translatable field with its own settings toggle.</li><li><strong>Added:</strong> MultilingualPress integration — auto-translate new connected posts at creation time (opt-in).</li><li><strong>Changed:</strong> Removed Requires Plugins: ai header — wp_ai_client_prompt() is native to WordPress 7.0; works with any configured AI provider.</li><li><strong>Changed:</strong> Admin notice now fires when no text-generation provider is configured.</li></ul><h3>1.0.0 - 2026-05-23</h3><ul><li><strong>Added:</strong> Block editor sidebar and Classic editor metabox with language selector and Translate button.</li><li><strong>Added:</strong> REST endpoint POST /wp-json/ai-translator/v1/translate.</li><li><strong>Added:</strong> WP-CLI command wp ai-translator translate for single-post and bulk translation.</li><li><strong>Added:</strong> Network admin settings page with global / per-site configuration mode.</li><li><strong>Added:</strong> Site admin settings page with title and content translation toggles.</li><li><strong>Added:</strong> Model recommendations table in the settings pages.</li></ul>",
"sections": {
"description": "Translate post titles and content from the WordPress editor using the native WordPress AI client (available in WP 7.0+). Multisite-ready with global or per-site configuration.",
"changelog": "<h3>1.2.1 - 2026-08-07</h3><ul><li><strong>Changed:</strong> Confirmed compatibility with WordPress 7.1. No functional changes.</li></ul><h3>1.2.0 - 2026-05-26</h3><ul><li><strong>Added:</strong> Configurable request timeout — new \"Request timeout\" setting (default 60 s, min 30 s, max 300 s) controls how long the server waits for an AI response before timing out.</li><li><strong>Added:</strong> Parallel chunked content translation — long post content is automatically split at block (Gutenberg) or paragraph (Classic editor) boundaries and translated in parallel, eliminating timeout errors on lengthy posts.</li><li><strong>Added:</strong> Progress indicator — the Translate button shows \"Translating… (2/5)\" while chunks are in flight.</li><li><strong>Added:</strong> New REST endpoint POST /wp-json/ai-translator/v1/translate-text for raw-text translation; used internally by the chunked content path.</li></ul><h3>1.1.0 - 2026-05-25</h3><ul><li><strong>Added:</strong> Excerpt translation — post_excerpt is now a translatable field with its own settings toggle.</li><li><strong>Added:</strong> MultilingualPress integration — auto-translate new connected posts at creation time (opt-in).</li><li><strong>Changed:</strong> Removed Requires Plugins: ai header — wp_ai_client_prompt() is native to WordPress 7.0; works with any configured AI provider.</li><li><strong>Changed:</strong> Admin notice now fires when no text-generation provider is configured.</li></ul><h3>1.0.0 - 2026-05-23</h3><ul><li><strong>Added:</strong> Block editor sidebar and Classic editor metabox with language selector and Translate button.</li><li><strong>Added:</strong> REST endpoint POST /wp-json/ai-translator/v1/translate.</li><li><strong>Added:</strong> WP-CLI command wp ai-translator translate for single-post and bulk translation.</li><li><strong>Added:</strong> Network admin settings page with global / per-site configuration mode.</li><li><strong>Added:</strong> Site admin settings page with title and content translation toggles.</li><li><strong>Added:</strong> Model recommendations table in the settings pages.</li></ul>"
},
"banners": {
"low": "",
"high": ""
},
"icons": {
"1x": "",
"2x": ""
}
}