In AtroCore, you can define the default appearance for an entity's list and detail pages using layout files. These files are located in the Resources/layouts folder, with each entity having its own subdirectory.


Layout Files

Each entity's layout is defined by three files within its dedicated directory (Resources/layouts/{EntityName}):

  • list.json: This file defines the columns for the entity's list view, which is typically a table. The link key can be used to make a column, such as name, clickable.

    Example: Category/list.json

    [
      { "name": "name", "link": true },
      { "name": "mainImage", "notSortable": true },
      { "name": "code" },
      { "name": "categoryRouteName" },
      { "name": "channels", "notSortable": true },
      { "name": "isActive" }  ]
  • detail.json: This file defines the layout for the entity's detail page, which is structured as a series of panels. Each panel contains rows, and each row can hold one or two fields.

    Example: Category/detail.json

    [
      {
          "label": "Details",
          "style": "default",
          "rows": [
              [
                  { "name": "isActive" },
                  false
              ],
              [
                  { "name": "name" },
                  { "name": "parent" }
              ],
              [
                  { "name": "description" },
                  { "name": "code" }
              ]
          ]
      }
    ]
  • relationships.json: This file lists the related entities that should be loaded and displayed on the detail page. By default, these relations are shown in a table using the related entity's standard list.json layout.

    Example: Category/relationships.json

    [
      { "name": "products" },
      { "name": "channels" }
    ]

If you need a different column layout for a related entity when viewed on a specific detail page, you can create a custom list layout file.

Name the file listIn{TargetEntityName}.json within the related entity's layout directory. For example, to customize how Category entities are listed on the Product detail page, create Resources/layouts/Category/listInProduct.json.

Example: Category/listInProduct.json

[
    { "name": "name", "link": true },
    { "name": "isActive" }
]

Extending Layouts with Listeners

To modify an existing entity's layout from another module, you should use a listener. The listener file is named {EntityName}Layout.php and should extend AbstractLayoutListener.

For instance, to add a new retailPrice field to the Product entity, you can create a listener to update its default layouts.

Example: {MyModuleNamespace}/Listeners/ProductLayout.php

<?php
namespace {MyModuleNamespace}\Listeners;

use Atro\Core\EventManager\Event;
use Atro\Listeners\AbstractLayoutListener;

class ProductLayout extends AbstractLayoutListener
{
    public function detail(Event $event)
    {
        // Don't modify layouts that have been customized in the UI.
        if (!$this->isCustomLayout($event)) {
            $result = $event->getArgument('result');
            // Add the new field to the detail view.
            $result[0]['rows'][] = [['name' => 'retailPrice'], false];
            $event->setArgument('result', $result);
        }
    }

    public function list(Event $event)
    {
        $relatedEntity = $this->getRelatedEntity($event);
        $result = $event->getArgument('result');

        if (!$this->isCustomLayout($event)) {
            // Check if the list is for the 'Category' entity's detail page.
            if ($relatedEntity === 'Category') {
                // If so, do nothing to avoid adding the new field.
                return;
            }

            // Otherwise, add the new field to the list view.
            $result[] = ['name' => 'retailPrice'];
        }

        $event->setArgument('result', $result);
    }
}

To learn more about extending features from Core or other module check here