4. Project

How to migrate the rest of your project to Mayd 2. Migrating your projects code will be the biggest part of work. A possible approach is to migrate component by component.

There are some breaking changes in Mayd 2. These changes and their migration strategies are explained below.

Page Types

  • The function getContentEntityClass was replaced by a new createContentEntity. The new function does not longer return the string name of your entity, but a new instance of it:

    Old:

    public function getContentEntityClass () : string
    {
        return BlocksContent::class;
    }

    New:

    public function createContentEntity () : Content
    {
        return new BlocksContent();
    }
  • The PageType class no longer provides a copyContent method. Please remove it completely.
  • The PageType class no longer provides a getConfig method. Please remove it completely.

Block Types

  • The method getBlockTypeClass is replaced by a new method createEntity:

    Old:

    public function getBlockTypeClass () : string
    {
        return Block::class;
    }

    New:

    public function createEntity () : Block
    {
        return new Block();
    }
  • The method getBlockFormType is replaced by a new method getFormType:

    Old:

    public function getBlockFormType () : ?string
    {
        return BlockForm::class;
    }

    New:

    public function getFormType () : string
    {
        return BlockForm::class;
    }
  • The method getAdminCardDetails is replaced by getSlotEntryData:

    Old:

    public function getAdminCardDetails (Block $block) : ?string
    {
        return "<p>Description</p>";
    }

    New:

    public function getSlotEntryData (Block $block) : ?SlotEntryData
    {
        return new SlotEntryData("Description");
    }

    You can use DeferredTranslation of the RadBundle to translate contents of your SlotEntryData:

    public function getSlotEntryData (Block $block) : ?SlotEntryData
    {
        return new SlotEntryData(new DeferredTranslation(
            "block-type.block.description.label", [] "backend"
        ));
    }
  • The method getBlockContainerCssClasses is removed. You can add a wrapping div -Tag with that class attribute around your block template.
  • The method getAdditionalEditActions is changed to getEditActions. You do not have to create a route for your crud manager anymore. There is a built-in action class that opens a crud-manager:

    Old:

    public function getAdditionalEditActions () : array
    {
        return [
            new EditAction("route.name", "icon", "translation.label"),
        ];
    }

    New:

    public function getEditActions (Block $block) : array
    {
        return [
            new CrudBlockEditAction(
                "translation.label",
                "translation.crud.modal_headline",
                EntryCrudManager::CRUD_KEY,
                "translation.crud.headline",
                ["block" => $block]
            ),
        ];
    }
  • The function copyBlockData is removed completely, as the command mayd:pages:copy-page has been removed.

CRUD Manager

  • Your crud managers have to implement the new CrudManagerInterface.
  • The CrudManagerInterface now just has four methods: getKey, configure, normalizeEntity, and getModel.
  • The model returned from getModel has to implement the CrudModelInterface.

    There is also a more specific SortableCrudModelInterface interface. Make sure to override the methods add and remove. And update the sort order within your new definition.

Entities

  • Entities with a slug can use the @Slug validation from Mayd. You can remove your old custom validator. Do not forget to add a @UniqueEntity(fields={"slug", ...}) annotation to the root of your entity.
  • All entities should implement RAD’s EntityInterface.

Content

  • The Content class implementation changed: it does no longer allow the $page to be passed in the constructor. You just have to remove it completely.
  • The Content class already uses the RadTraits\IdTrait and the RadTraits\TimestampsTrait. Your entity does not need to implement them themselves.
  • The Content class already implements the EntityInterface. Your entity does not need to implement it themselves.
  • The Content class requires your implementation to provide a getAllSlots function that returns an array of slots. If your page does not have any, just return an empty array.

Slot

  • The constructor of your Slot does no longer need the parameter string $type. Please remove it completely.
  • The Slot class requires the implementation of a getContext method.
  • The Slot class no longer requires the implementation of a getPage method. Please remove it completely. You should however add it to the ContentContext in YourSlot::getContext().

Block

  • The constructor of your Block does no longer need the parameter Slot $slot. Please remove it completely.
  • If your block implements a __clone() method, make sure to call the parent parent::__clone(); method in it.

If your block contains attached relations (like block entries), your block model should implement the EventSubscriberInterface and listen to the BlockRemoveEvent, to also mark the attached relations for removal.

Block Entries

  • All block entries should now implement the BlockEntryInterface.

Models

  • All models should now extend the Model base class from the RAD Bundle.

The models don’t flush automatically in the ->add(), ->update() and ->remove() methods anymore. Instead you must explicitly call ->flush() from the outside.

It’s always the responsibility of the top most component (typically Controller or Command) to flush. Use this pattern:

$model->update($entity)->flush();

The model itself should never flush internally.

Controller

Page

  • The parameters Page $page, AbcBlocksContent $content are no longer directly provided. Instead a PageRequestContext $context is provided. This context contains the page and the content. You can render your template like this:

    public function index (PageRequestContext $context) : Response
    {
        return $this->render("index.html.twig", $context->mergeParameters([
            "currentLocale" => $context->getLocale(),
            "website" => $context->getWebsite(),
        ]));
    }

    By using the mergeParameters method, context, page, and content are automatically passed to your template.

    You can then include the context in your base layout (e.g. layout.html.twig)

    ...
    {#- @var \Mayd\Pages\Request\RequestContext context|null -#}
    {%- set context = context ?? null -%}
    ...
  • The render_slot twig function now requires the context as second parameter.

Forms

  • Mayd provides a built in RichTextType.

RTE

  • If your project uses the old RTE, that stores data as mobiledoc, you have to migrate your data to html, as the new RTE stores its data as html.
  • The RTE provides a built-in twig function rich_text, that replaces previous render_content() implementations.

Frontend Templates

  • You need to implement one or more FrondendTheme s. These define the required assets, body classes and available menu locations.

    class ProjectNameTheme extends FrontendTheme
    {
        /**
         * @inheritDoc
         */
        public function getHeaderAssets () : array
        {
            return [
                "@app/css/projectName.css",
            ];
        }
    
    
        /**
         * @inheritDoc
         */
        public function getFooterAssets () : array
        {
            return [
                "@app/js/projectName.js",
            ];
        }
    
    
        /**
         * @inheritDoc
         */
        public function getBodyClass () : ?string
        {
            return "projectName";
        }
    
    
        public function getMenuLocations () : array
        {
            return [
                new MenuLocation("footer"),
                new MenuLocation("service"),
            ];
        }
    }
  • The use of these Templates is important, especially in connection with the change in the structure of your root twig template (extension of @MaydCore/frontend.html.twig, described in section Twig Templates.

    Make sure to select the theme for every application. You can configure that in the application backend.

Twig Templates

  • Your frontend root template should extend the @MaydCore/frontend.html.twig template:
{%- extends "@MaydCore/frontend.html.twig" -%}

Please be aware that the usage of that template may change some of your block definitions. E.g. tracking_head would move to assets_head

  • Block templates moved from templates/blocks to templates/block.
  • The render_slot twig function now requires the context as second parameter.
  • The namespace @build may have changed to @app depending on your configuration.
  • The path to your main assets (##.js and ##.css) may have changed, depending on your kaba configuration.
  • The function file_preview_url is replaced by image_url. The new function requires a image size. This size is configured in config/packages/mayd.yaml:

    mayd_files:
        image_sizes:
            slider:
                width: 844
                height: 720 # optional
                mode: cover # optional (contain / cover)
            content:
                width: 844

Translations

  • Mayd 2 uses the intl-icu translation format. This entails several syntax changes, for example:

    • Placeholders are no longer formated as %placeholder% but now as: {placeholder}
    • transChoice is now gone and is transparently natively supported in regular translation keys with ->trans().
  • Translation keys (especially those generated by Mayd e.g. for page-types) are now written in kebab-case.

Configuration

  • If your project has a config/packages/twig.yaml and exception_controller defined in it, you need to remove it. This is replaced by a mayd built-in controller and now defined in config/packages/framework.yaml
  • config/packages/gluggi_bundle.yaml is now config/packages/gluggi.yaml and may require some changes, as you may have a new asset target file structure.