Creating new Layout Components

At a high level Layout components are basic JSON objects created by the CMS but controlled by the API.

We allow or disallow each component per publication, this is controlled in the clients core_xxx module, JP works by disallowing unwanted components, the rest are an opt-in style in the .module file.

Having created a new component if it requires articles there is also a file that needs editing to say how many articles. For example ArticleX3 has 3 articles in it and in the Content API's TermPageController you will have to add the number of articles to the switch case at line 133.

eg from the TermPageController:

    case 'HeadShotX3':
    case 'ArticleX3':
    case 'ArticleX3Insider':
    case 'ArticleX3Small':
    case 'ArticleX3PlusMPU':
    case 'ArticleX3PlusDMPU':
    case 'HeroPlus2ArticlesPlusDMPU':
    case 'HeroCustomPlus2ArticlesPlusDMPU':
    case 'HeroPlus2Articles':
    case 'HeroPlus2ArticlesNewsletter':
    case 'ArticleX2PlusQuoteHero':
    case 'PopularVideos':
    case 'ArticleX3PlusTeaser':
        self::processComponentItem(3, $component, $key, $termId, $componentRows);

Not all components get articles from the API but those that do get them from either

  1. A specific section/topic/author term that is either from the page that you are on or specified manually by an editor in the CMS Layout manager.
  2. Manual Lists can also be selected as the source of articles for a component.

The Component PHP Class

Each component needs a class in the layout modules' layout directory

/brightsites-api/drupal/web/modules/custom/flowz/layout/src/Layout

If you have a look at the list of classes they all begin with either Section or Sidebar depending on where they are intended to be used.

Example Class

<?php

namespace Drupal\layout\Layout;

/**
 * Class SectionArticleX4PlusDMPU
 *
 * @package Drupal\layout\Layout
 */
class SectionArticleX4PlusDMPU extends AbstractLayoutComponent
{
    /**
     * @param $vars
     * @param $component
     * @return array
     */
    public static function get(&$vars, $component): array
    {
        $articles = [];
        for ($i = 0; $i < 4; $i++) {
            if (!empty($vars) && is_array($vars)) {
                $articles[] = array_shift($vars);
            }
        }

        return [
            'type' => self::getType(),
            'labelText' => empty($component->LabelText) ? null : $component->LabelText,
            'labelLink' => empty($component->LabelLink) ? null : $component->LabelLink,
            'useAuthorImage' => empty($component->UseAuthorImage) ? false : $component->UseAuthorImage,
            'ad' => [
                'type' => 'dmpu',
                'alignment' => empty($component->AdAlignment) ? 'Right' : $component->AdAlignment,
                'adSource' => empty($component->AdSource) ? null : $component->AdSource,
            ],
            'updated' => $component->updated ?? null,
            'taboolaExcludeArticles' => $component->taboolaExcludeArticles ?? null,
            'articles' => $articles,
        ];
    }

    /**
     * @return string
     */
    public static function getType(): string
    {
        return 'ArticleX4PlusDMPU';
    }

    /**
     * @return string
     */
    public static function getName(): string
    {
        return '4 articles + DMPU';
    }

}

The classes have an interface that must be observed, it has 3 methods, get, getType & getName

getType returns the name of the class but without the Section or Sidebar prefix.

getName returns the human-readable name of the component used in the CMS.

get This is what is called when the API is building the section pages, $vars is normally an array of articles but can be a sting and $component is the Object from the JSON the CMS created for this component.

In this example we loop over the articles in the $vars array to build an articles array

Then return an array with the properties needed by the front end, we look for some specific things in te JSON to populate specific things in the return value of this method, this prevents people just adding random stuff.

To create a new one just copy this structure and check other similar classes that do similar things.