filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
17.59k stars 2.75k forks source link

Translation on RelationShip Issue #11175

Closed abbasmashaddy72 closed 4 months ago

abbasmashaddy72 commented 7 months ago

Package

filament/spatie-laravel-translatable-plugin

Package Version

v3.2

Laravel Version

v10.10

Livewire Version

v3.0

PHP Version

PHP 8.2

Problem description

I have topic_id in Post & Articles connected with topic_id with relation topic, but when I tried to set locales for the Article & Post Title and other content that was added worked perfectly, but topic related data does not work I mean it does not change the translation When I tried to debug it is working perfectly but in view it does not change

Forms\Components\Select::make('topic_id')
    ->relationship('topic')
    ->getOptionLabelFromRecordUsing(function (Topic $topic, $livewire) {
        Log::info('Active Locale: ' . $livewire->activeLocale);

        $translatedTitle = $topic->getTranslation('title', $livewire->activeLocale);

        Log::info('Translated Title: ' . $translatedTitle);

        return $translatedTitle ?? $topic->title; // Fallback to default title if translation is not available
    })
    ->searchable()
    ->live()
    ->required(),
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Deserunt.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Incidunt sunt est animi.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Totam libero aspernatur est.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Et tempore voluptatum.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Nemo et sint.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Repellat consequatur dolores nostrum numquam.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Earum tenetur.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Aut sunt blanditiis blanditiis ut.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Provident vel.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Qui voluptas ut.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Sapiente ut exercitationem assumenda nesciunt.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Eveniet voluptatem consequuntur eum.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Ipsa ipsa dicta corrupti.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Qui veniam nulla ut earum.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: At asperiores consequuntur.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Ut.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Voluptatibus quisquam laboriosam eligendi dolores provident distinctio id deserunt.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Earum soluta.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Voluptatem voluptatibus dolores.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Rerum esse aut.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Dolore.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Quos modi illo est et molestiae.  
[2024-01-31 12:53:57] local.INFO: Active Locale: en  
[2024-01-31 12:53:57] local.INFO: Translated Title: Hic cum.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Eum et rerum.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Nihil voluptate voluptas est aliquid debitis qui doloremque non voluptate corporis.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Alias in consequuntur officiis.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Iste qui sunt omnis et eaque in.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Quas hic.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Incidunt animi perspiciatis natus doloremque commodi aut delectus.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Et ut.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Voluptatem qui inventore nobis itaque et magni.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Voluptatem libero.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Vero et modi veniam quidem.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Dolorum architecto ut deleniti repudiandae quidem sit non.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Rem dolorum rerum pariatur libero rerum.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Tempore distinctio autem commodi.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Ut sequi perferendis distinctio consequatur accusantium.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Esse hic eum saepe officiis sapiente.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Eveniet consectetur numquam architecto consectetur architecto quo nostrum.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Maiores qui ut non.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Blanditiis dolorum provident non suscipit.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Impedit sunt odio illo.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Ea reiciendis facere eligendi dignissimos voluptate architecto.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Quo corrupti ut illum.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Delectus eaque.  
[2024-01-31 12:54:05] local.INFO: Active Locale: ar  
[2024-01-31 12:54:05] local.INFO: Translated Title: Omnis dignissimos exercitationem praesentium.  

Expected behavior

It should have changed the select locale title

Steps to reproduce

  1. Installed Package filament/spatie-laravel-translatable-plugin

  2. Set up the Models and Migrations Accordingly: Article Model:

    
    <?php

namespace App\Models;

use App\Concerns\HasMeta; use App\Concerns\Sluggable; use App\Concerns\HasFeaturedImage; use App\Concerns\HasPublishedScope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Spatie\Translatable\HasTranslations;

class Article extends Model { use HasPublishedScope, Sluggable, HasFactory, HasMeta, SoftDeletes, HasFeaturedImage, HasTranslations;

public $translatable = ['title', 'content', 'excerpt'];

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'title',
    'slug',
    'status',
    'author_id',
    'content',
    'excerpt',
    'published_at',
];

/**
 * The attributes that should be cast to native types.
 *
 * @var array
 */
protected $casts = [
    'published_at' => 'datetime',
    'content' => 'array',
];

protected $with = [
    'meta',
];

public function getPublicUrl()
{
    return route('articles.show', $this);
}

public function topic(): BelongsTo
{
    return $this->belongsTo(Topic::class, 'topic_id', 'id');
}

public function author(): BelongsTo
{
    return $this->belongsTo(User::class, 'author_id');
}

}


Topic Model:

<?php

namespace App\Models;

use App\Concerns\HasMeta; use App\Concerns\Sluggable; use App\Concerns\HasFeaturedImage; use App\Concerns\HasPublishedScope; use Illuminate\Database\Eloquent\Model; use Spatie\Translatable\HasTranslations; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory;

class Topic extends Model { use HasPublishedScope, Sluggable, HasFactory, HasMeta, SoftDeletes, HasFeaturedImage, HasTranslations;

public $translatable = ['title', 'content', 'excerpt'];
/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'title',
    'slug',
    'status',
    'excerpt',
    'content',
];

/**
 * The attributes that should be cast to native types.
 *
 * @var array
 */
protected $casts = [
    'id' => 'integer',
    'indexable' => 'boolean',
    'content' => 'array',
];

protected $with = [
    'meta',
];

public function getPublicUrl()
{
    return route('topics.show', $this);
}

public function articles()
{
    return $this->hasMany(Article::class);
}

}



3. Generated the Resources and modified as per the instructions provided in the packages.

Images:
English
![English](https://github.com/filamentphp/filament/assets/55267488/5c1ccc85-15d3-4ccd-9744-dd6171e354e9)
Arabic
![Arabic](https://github.com/filamentphp/filament/assets/55267488/0b78b294-9523-4cac-a85b-da7b43d39c94)

### Reproduction repository

https://github.com/abbasmashaddy72/filament-starter-kit

### Relevant log output

_No response_
leandrocfe commented 7 months ago

Does it work without ->searchable()?

abbasmashaddy72 commented 7 months ago

I had not checked it but When loading of data it only loads Default language Example English

Does it work without ->searchable()?

leandrocfe commented 7 months ago

The issue arises because of searchable() using JS. I thought about using ->searchable(fn (string $operation): bool => $operation !== 'view') to disable searching on the view page, but this would persist as a problem on the Edit Page. Honestly, it's not a big deal since the field reloads options when you click it anyway.

Additionally, you could use this snippet instead of getOptionLabelFromRecordUsing

->relationship('topic', fn (Component $livewire): string => 'title->'.$livewire->activeLocale)
abbasmashaddy72 commented 7 months ago

The issue arises because of searchable() using JS. I thought about using ->searchable(fn (string $operation): bool => $operation !== 'view') to disable searching on the view page, but this would persist as a problem on the Edit Page. Honestly, it's not a big deal since the field reloads options when you click it anyway.

Additionally, you could use this snippet instead of getOptionLabelFromRecordUsing

->relationship('topic', fn (Component $livewire): string => 'title->'.$livewire->activeLocale)

Thanks,

I will check it out brother and let you know

ahmedkalash commented 6 months ago

@abbasmashaddy72

First, I have tried the way you mentioned, and worked for me without any problems so check the record in the database. make sure it is a valid JSON and it contains the Arabic translation correctly in a way that you can fetch it outside Filament.

here is what I tried


>getOptionLabelFromRecordUsing(function (ProductCategory $record, $livewire) {
                        $translatedTitle = $record->getTranslation('name', $livewire->activeLocale);
                        return $translatedTitle ?? $record->name; // Fallback to default title if translation is not available
                    })

Second, you can try something like that


->relationship('categories', "name", function (Builder $query,$livewire){
                        return $query;
                        return $query->selectRaw("JSON_EXTRACT(name, '$.{$livewire->activeLocale}') AS name");
                    })

Third, If the problem still present you can use relation manager instead of Select

Fourth, it worth mention that I had a similar problem with translating relationship attributes in the previous versions of Filament but after updating Filament and the filament/spatie-laravel-translatable-plugin some of them were solved and some other sill present.

Please let me know if you solved it

abbasmashaddy72 commented 6 months ago

@abbasmashaddy72

First, I have tried the way you mentioned, and worked for me without any problems so check the record in the database. make sure it is a valid JSON and it contains the Arabic translation correctly in a way that you can fetch it outside Filament.

here is what I tried


>getOptionLabelFromRecordUsing(function (ProductCategory $record, $livewire) {
                        $translatedTitle = $record->getTranslation('name', $livewire->activeLocale);
                        return $translatedTitle ?? $record->name; // Fallback to default title if translation is not available
                    })

Second, you can try something like that


->relationship('categories', "name", function (Builder $query,$livewire){
                        return $query;
                        return $query->selectRaw("JSON_EXTRACT(name, '$.{$livewire->activeLocale}') AS name");
                    })

Third, If the problem still present you can use relation manager instead of Select

Fourth, it worth mention that I had a similar problem with translating relationship attributes in the previous versions of Filament but after updating Filament and the filament/spatie-laravel-translatable-plugin some of them were solved and some other sill present.

Please let me know if you solved it

Hi @ahmedkalash I tried it, The Second one does not work.

But the First one only Shows the First Default I set for Example I have set en as Default it only shows the en values not the other language

abbasmashaddy72 commented 6 months ago

The issue arises because of searchable() using JS. I thought about using ->searchable(fn (string $operation): bool => $operation !== 'view') to disable searching on the view page, but this would persist as a problem on the Edit Page. Honestly, it's not a big deal since the field reloads options when you click it anyway.

Additionally, you could use this snippet instead of getOptionLabelFromRecordUsing

->relationship('topic', fn (Component $livewire): string => 'title->'.$livewire->activeLocale)

Hi @leandrocfe I tried this too showing this Error when Changing Language:

Filament\Forms\Components\Select::isOptionDisabled(): Argument #2 ($label) must be of type string, null given, called in /home/abbasmashaddy72/Documents/Sites/Dynamic/cms/vendor/filament/forms/src/Components/Select.php on line 187
Forms\Components\Select::make('parent_id')
->relationship('parent', fn (Component $livewire): string => 'name->' . $livewire->activeLocale)
// ->getOptionLabelFromRecordUsing(function (Menu $record, $livewire) {
//     $translatedTitle = $record->getTranslation('name', $livewire->activeLocale);
//     return $translatedTitle ?? $record->name; // Fallback to default title if translation is not available
// })
->searchable(false)
->live()
->default(null),
abbasmashaddy72 commented 6 months ago

I am attempting to use the relationship method to retrieve multi-language data, but it doesn't seem to work for loading. However, it successfully saves the data.

Upon inspecting the relationship method, particularly its second argument, which is a boolean, I suspect this might be the reason for the issue.

Here is the code for the second argument code that was give before:

->relationship('topic', fn (Component $livewire): string => 'title->'.$livewire->activeLocale)

The method signature for relationship is as follows:

public function relationship(string $name, bool | Closure $condition = true): static

For context, here is an excerpt from my relationship code:

<?php

namespace App\Components;

use Filament\Forms;
use Livewire\Component;
use Illuminate\Support\Str;
use Awcodes\Curator\Components\Forms\CuratorPicker;

class SEOMeta
{
    public static function make(): Forms\Components\Group
    {
        return Forms\Components\Group::make()
            ->relationship('seoMeta')
            ->columns(['md' => 2])
            ->schema([
                Forms\Components\Group::make([
                    Forms\Components\TextInput::make('title')
                        ->label('Title')
                        ->required(),
                    Forms\Components\Textarea::make('description')
                        ->label('Description')
                        ->rows(3)
                        ->required(),
                    Forms\Components\Toggle::make('indexable')
                        ->label('Indexable'),
                ]),
                CuratorPicker::make('og_image')
                    ->label('OG Image')
                    ->lazyLoad()
                    ->constrained(true)
                    ->visible()
                    ->relationship('ogImage', 'og_image')
                    ->helperText('Leave empty to use the default. This will also be used on any resources that utilize a featured image, such as blog posts.'),
            ])->columnSpanFull();
    }
}
gabyyro commented 5 months ago

Have same issue.

jmcondeprol commented 5 months ago

Yeah, more or less same issue here, and I think my implementation is more simple; not sure the problem is related with the searchable() method, as pointed by @leandrocfe. I'm just trying to show the parent name of category in my resource table; as you can see on the screenshots, it works fine for the name column, but it's not changing for the relationship.

image

image

image

image

danharrin commented 4 months ago

I am posting this same message across all Spatie Translatable issues & PRs

Hey all! Wanted to update you on where we're at with the translatable plugin.

I really appreciate your patience while this issue has been active. While I created the plugin for the community, I've never actually had a project where I needed to use it, and that's the same for the rest of the Filament team. As such, it's the reason why the plugin hasn't had as much attention as the others, and is much more unstable: I just don't have the environment to test all the use cases, nor the motivation to make it truly great.

As such, I put out a post a month ago and asked who in the community uses the plugin and has knowledge of plugin development. Luckily, Lara Zeus and Mohamed Sabil stepped forward, who are both authors of popular Filament plugins and are trusted by the community.

We are strongly considering handing over maintenance of the plugin to those developers, for the good of the community. You can find their fork at https://github.com/lara-zeus/translatable.

Since the new developers have lots of experience with the plugin and active projects that use it, they should be able to help debug issues easier and make a much more stable experience for other users.

If their work goes well until v4 is released, we will likely retire the plugin at that point and recommend the fork as an official replacement. If it does not go as expected and the community is unhappy, then we will reconsider this decision. I am closing this for now, and if we decide to take maintenance back officially then we will probably reopen it.

The existing plugin will continue to receive security updates indefinitely. Please let me know if you have any further questions.

Many thanks, Dan

Khant-Nyar commented 3 months ago

I am posting this same message across all Spatie Translatable issues & PRs

Hey all! Wanted to update you on where we're at with the translatable plugin.

I really appreciate your patience while this issue has been active. While I created the plugin for the community, I've never actually had a project where I needed to use it, and that's the same for the rest of the Filament team. As such, it's the reason why the plugin hasn't had as much attention as the others, and is much more unstable: I just don't have the environment to test all the use cases, nor the motivation to make it truly great.

As such, I put out a post a month ago and asked who in the community uses the plugin and has knowledge of plugin development. Luckily, Lara Zeus and Mohamed Sabil stepped forward, who are both authors of popular Filament plugins and are trusted by the community.

We are strongly considering handing over maintenance of the plugin to those developers, for the good of the community. You can find their fork at https://github.com/lara-zeus/translatable.

Since the new developers have lots of experience with the plugin and active projects that use it, they should be able to help debug issues easier and make a much more stable experience for other users.

If their work goes well until v4 is released, we will likely retire the plugin at that point and recommend the fork as an official replacement. If it does not go as expected and the community is unhappy, then we will reconsider this decision. I am closing this for now, and if we decide to take maintenance back officially then we will probably reopen it.

The existing plugin will continue to receive security updates indefinitely. Please let me know if you have any further questions.

Many thanks, Dan

why not merge with zeus !!