Gói này cung cấp một đặc tính cho các lớp quản trị và một đặc tính cho các thực thể. Cùng nhau, chúng thêm các trường và các hành động cần thiết cho việc quản lý nhiều biến thể ngôn ngữ.
Các locale đến từ các trang Sonata Page. Quản trị sau đó hiển thị các biến thể có sẵn và cho phép liên kết các bản ghi của cùng một nhóm dịch thuật.
Màn hình
- Chỉnh sửa một bản dịch trên trang web đã chọn

- Danh sách nội dung trong ngôn ngữ đã chọn

- Tạo một bản dịch từ biến thể hiện hành

Ví dụ về triển khai cho một lớp quản trị đơn giản
Tệp thực thể
<?php
namespace App\Entity;
use App\Repository\SimpleTestRepository;
use Doctrine\ORM\Mapping as ORM;
use Partitech\SonataExtra\Traits\EntityTranslationTrait;
#[ORM\Entity(repositoryClass: SimpleTestRepository::class)]
class SimpleTest
{
use EntityTranslationTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
// ...
}
Tệp quản trị
<?php
declare(strict_types=1);
namespace App\Admin;
use Partitech\SonataExtra\Attribute\AsAdmin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Partitech\SonataExtra\Controller\Admin\TranslationController;
use Partitech\SonataExtra\Traits\AdminTranslationTrait;
#[AsAdmin(
manager_type: 'orm',
label: 'Simple Entity',
model_class: \App\Entity\SimpleTest::class,
)]
final class SimpleTestAdmin extends AbstractAdmin
{
use AdminTranslationTrait;
// ...
}
Chỉ cần thêm các trait vào các lớp quản trị và thực thể. Sau đó, chạy các lệnh sau:
bin/console doctrine:schema:update --force
bin/console cache:clear
Nếu bạn đã có một bộ điều khiển, chỉ cần thêm đặc điểm của bộ điều khiển
class MenuController extends Controller
{
use \Partitech\SonataExtra\Traits\ControllerTranslationTrait;
}
Bạn cũng có thể gọi hành động tạo bản dịch bằng cách sử dụng bộ điều khiển mở rộng như một dịch vụ
use \Partitech\SonataExtra\Controller\Admin\TranslationController;
class MenuController extends Controller
{
use \Partitech\SonataExtra\Traits\ControllerTranslationTrait;
private $TranslationController;
#[Required]
public function autowireDependencies(
TranslationController $TranslationController
): void {
$this->TranslationController = $TranslationController;
}
public function createTranslationAction($id, $from_site, $to_site, $fqcn): Response
{
return $this->TranslationController->createTranslationAction($id, $from_site, $to_site, $fqcn);
}
}
Cấu hình của quản trị viên
Trait có cấu hình riêng của nó. Nếu bạn có một phương thức cấu hình trong quản trị viên của mình, chỉ cần đảm bảo gọi cấu hình của trait như sau:
#[AsAdmin(
manager_type: 'orm',
group: 'Admin',
label: 'Test',
model_class: \App\Entity\Test::class
)]
final class TestAdmin extends AbstractAdmin
{
use AdminTranslationTrait;
protected function configure(): void
{
$this->configureTrait();
$this->setTemplate('edit', '@PartitechSonataMenu/CRUD/edit.html.twig');
}
}
Cấu hình đường dẫn quản trị
Đặc điểm thêm tuyến đường riêng của nó để tạo bản dịch. Nếu người dùng cũng thêm các tuyến đường, họ phải cấu hình các tuyến đường của họ như sau:
#[AsAdmin(
manager_type: 'orm',
group: 'Admin',
label: 'Test',
model_class: \App\Entity\Test::class
)]
final class TestAdmin extends AbstractAdmin
{
use AdminTranslationTrait;
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$this->configureTraitRoutes($collection);
$collection->remove('show');
}
// ...
}
Lời kêu gọi configureTraitRoutes() thêm các tuyến đường cần thiết trước khi cấu hình các tuyến đường của riêng bạn. Điều này chỉ cần nếu configureRoutes được triển khai trong lớp quản trị.
Tính tương thích của dịch máy
Tính năng đa ngôn ngữ tương thích với công cụ dịch tự động của chúng tôi thông qua « API dịch » (xem dịch vụ_thông minh.md).
Thêm thuộc tính #[Translatable] để làm cho một trường đủ điều kiện để dịch tự động thông qua API, sử dụng nhà cung cấp của ứng dụng (xem dịch vụ_thông minh.md).
use Partitech\SonataExtra\Attribute\Translatable;
#[ORM\Column(type: 'text', nullable: true)]
#[Translatable]
private ?string $description=null;
// ...
Tính năng này tương thích với các mối quan hệ OneToMany. Trong trường hợp này, hãy thêm chú thích cả vào mối quan hệ thực thể và vào các trường của thực thể liên quan.
Khi dịch, đối tượng trước tiên được nhân bản, sau đó được dịch. Việc nhân bản tự động phù hợp với một đối tượng đơn giản; đối với một thực thể phức tạp, hãy triển khai rõ ràng phương thức __clone(). Cấu trúc cây của menu không thể được sao chép mà không có một chức năng sao chép nội bộ.
Về các trường slug
Vì slug phải là duy nhất, trong quá trình nhân bản, quá trình sẽ tìm kiếm một phương pháp $object->getSlug(). Nếu phương pháp tồn tại, quy trình sẽ kiểm tra xem thuật ngữ đã được dịch hay chưa. Nếu thuật ngữ giống nhau, nó sẽ thêm tiền tố giá trị với ngôn ngữ của nó.
if (method_exists($clonedObject, 'setSlug') && $clonedObject->getSlug()==$object->getSlug()) {
$slugger = new AsciiSlugger();
$slug=$slugger->slug($this->site->getLocale().'-'.$clonedObject->getSlug())->lower();
$clonedObject->setSlug($slug);
}
Tích hợp phân loại Sonata đa ngôn ngữ
Để giữ lại thông tin dịch của SonataClassificationTag và SonataClassificationCategory, sử dụng các lớp quản trị do Sonata Extra cung cấp.
Trong cấu hình sonata_classification.yaml, giữ cấu hình của bạn như sau:
sonata_classification:
class:
category: App\Entity\SonataClassificationCategory
collection: App\Entity\SonataClassificationCollection
context: App\Entity\SonataClassificationContext
tag: App\Entity\SonataClassificationTag
Trong thực thể của bạn, hãy chắc chắn thêm đặc điểm:
- ThẻPhânLoạiSonata.php
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\DBAL\Types\Types;
use App\Repository\SonataClassificationTagRepository;
use Sonata\ClassificationBundle\Entity\BaseTag;
use Partitech\SonataExtra\Traits\EntityTranslationTrait;
#[ORM\Entity(repositoryClass: SonataClassificationTagRepository::class)]
#[ORM\Table(name: 'classification__tag')]
#[ORM\HasLifecycleCallbacks]
class SonataClassificationTag extends BaseTag
{
use EntityTranslationTrait;
#[ORM\Id]
#[ORM\Column(type: Types::INTEGER)]
#[ORM\GeneratedValue]
protected ?int $id = null;
public function getId(): ?int
{
return $this->id;
}
}
- PhânLoạiSonata.php
<?php
namespace App\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Sonata\ClassificationBundle\Entity\BaseCategory;
use Partitech\SonataExtra\Traits\EntityTranslationTrait;
#[ORM\Entity]
#[ORM\Table(name: 'classification__category')]
class SonataClassificationCategory extends BaseCategory
{
use EntityTranslationTrait;
#[ORM\Id]
#[ORM\Column(type: Types::INTEGER)]
#[ORM\GeneratedValue]
protected ?int $id = null;
public function getId(): ?int
{
return $this->id;
}
}
Sử dụng các lớp quản trị nhãn và danh mục được cung cấp bởi Sonata Extra. KHÔNG SỬ DỤNG nhãn và danh mục quản trị của gói sonataClassification. Chúng sẽ không có các trường theo dõi cần thiết cho đa ngôn ngữ.
- sonata_admin.yaml
cms:
icon: fa fa-pencil
label: CMS
keep_open: true
items:
- Partitech\SonataExtra\Admin\ArticleAdmin
- sonata.page.admin.page
- sonata.page.admin.shared_block
- Partitech\SonataExtra\Admin\SliderAdmin
- Partitech\SonataExtra\Admin\FaqCategoryAdmin
- Partitech\SonataExtra\Admin\TagAdmin
- Partitech\SonataExtra\Admin\CategoryAdmin
Trạm kiểm soát
Trước khi thêm một bản dịch, hãy kiểm tra rằng các trang Sonata Page có các ngôn ngữ địa phương mong đợi và chỉ có một mục của nhóm được đặt làm phiên bản mặc định. Sau đó, hãy thử tạo, chỉnh sửa và điều hướng giữa các biến thể với một người dùng có quyền hạn hạn chế.