Al manejar contenido multilingüe, suele ser más eficiente almacenar las traducciones en una columna JSON en lugar de filas individuales para cada atributo. Este enfoque consolida las traducciones en una sola columna, lo que simplifica la gestión y recuperación de datos.
Mejoraremos nuestro modelo y tabla de traducción para usar una columna JSON para almacenar traducciones. Esto implicará actualizar el esquema de la tabla y modificar el rasgo traducible para manejar datos JSON.
Paso 1: Crear migración de la tabla de traducciones
Si la tabla de traducciones aún no existe, crea una nueva migración:
php artisan make:migration create_translations_table
Paso 2: Definir la estructura de la tabla
Abra el archivo de migración generado en base de datos/migraciones. Para una nueva tabla, defínala de la siguiente manera:
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateTranslationsTable extends Migration { public function up() { Schema::create('translations', function (Blueprint $table) { $table->id(); $table->string('locale'); // Stores the locale, e.g., 'en', 'fr' $table->string('translatable_type'); // Stores the related model type, e.g., 'Post', 'Product' $table->unsignedBigInteger('translatable_id'); // Stores the ID of the related model $table->json('translations'); // Stores all translations as a JSON object $table->timestamps(); }); } public function down() { Schema::dropIfExists('translations'); } }
Paso 3: ejecutar la migración
Aplica la migración a tu base de datos:
php artisan migrate
Paso 4: Crear el modelo de traducción
A continuación, cree el modelo de traducción para manejar la relación polimórfica:
php artisan make:model Translation
En el modelo de Traducción, defina la relación polimórfica:
class Translation extends Model { protected $fillable = ['locale', 'translatable_type', 'translatable_id', 'translations']; protected $casts = [ 'translations' => 'array', ]; public function translatable() { return $this->morphTo(); } }
Para que el manejo de la traducción sea reutilizable en múltiples modelos, crearemos un rasgo traducible que cargará automáticamente el contenido traducido según la configuración regional seleccionada por el usuario. Además, agregaremos un mecanismo alternativo para cargar contenido desde la configuración regional predeterminada si no hay traducción disponible para la configuración regional seleccionada.
Paso 1: Crear el rasgo traducible con manejo JSON
namespace App\Traits; use App\Models\Translation; use Illuminate\Support\Facades\App; trait Translatable { public static function bootTranslatable() { static::retrieved(function ($model) { $model->loadTranslations(); }); } public function translations() { return $this->morphMany(Translation::class, 'translatable'); } public function loadTranslations() { $locale = App::getLocale(); $defaultLocale = config('app.default_locale', 'en'); // Fallback to the default locale // Try to load translations for the current locale $translation = $this->translations()->where('locale', $locale)->first(); if (!$translation && $locale !== $defaultLocale) { // If no translations are found for the current locale, fallback to the default locale $translation = $this->translations()->where('locale', $defaultLocale)->first(); } if ($translation) { $translations = $translation->translations; foreach ($translations as $key => $value) { $this->{$key} = $value; } } } public function addTranslations(array $translations, $locale = null) { $locale = $locale ?? App::getLocale(); return $this->translations()->updateOrCreate( ['locale' => $locale], ['translations' => $translations] ); } }
Paso 2: aplique el rasgo traducible a su modelo
Agregue el rasgo Traducible a cualquier modelo que requiera soporte de traducción.
namespace App\Models; use App\Traits\Translatable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Translatable; protected $fillable = ['title', 'content']; }
Agregar traducciones como un objeto JSON:
$post = Post::create(['title' => 'Default Title', 'content' => 'Default Content']); // Adding translations $post->addTranslations([ 'title' => 'Hello World', 'content' => 'Welcome to our website' ], 'en'); $post->addTranslations([ 'title' => 'Bonjour le monde', 'content' => 'Bienvenue sur notre site Web' ], 'fr');
Recuperando modelos traducidos
Cuando recupere el modelo de publicación, cargará automáticamente el contenido traducido según la configuración regional actual o recurrirá a la configuración regional predeterminada si es necesario:
App::setLocale('fr'); $post = Post::find(1); echo $post->title; // Displays "Bonjour le monde" if French translation exists App::setLocale('es'); $post = Post::find(1); echo $post->title; // Displays "Hello World" as it falls back to the English translation
Mostrar contenido traducido en vistas
En tus vistas de Blade, puedes mostrar el contenido traducido como cualquier otro atributo del modelo:
{{ $post->title }}
{{ $post->content }}
Conclusión
Al utilizar una columna JSON para almacenar traducciones e implementar un mecanismo alternativo, agiliza la administración de contenido multilingüe en su aplicación Laravel. Este enfoque consolida las traducciones en una sola columna, lo que simplifica el manejo de datos y hace que su código base sea más fácil de mantener. Ya sea que esté creando un blog, un sitio de comercio electrónico o cualquier aplicación multilingüe, este método garantiza una experiencia de usuario fluida y eficiente.
¡Disfrutar!
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3