Skip to content

AMP

Intro

XalokNext comes with some features to ease developing AMP pages.

Platform template

Defining

One can define a template to be used only for a specific platform (AMP, in this case).

To do so, one needs to create a twig file with the -__PLATFORM_NAME__ suffix (e.g. src/App/Bundle/CmsBundle/Resources/views/Template/Article/default-amp.html.twig). Usually this file should overwrite the "non-platform" one (e.g. default.html.twig) and overwrite the blocks that need special HTML for the given platform.

Using

To render the article using the given platform, one needs to pass the platform name as a parameter to the wf_cms_render_page function.

Example: Display the article using the template for the amp platform (default-amp.html.twig):

html
    {{ wf_cms_render_page(pageSlug, pageVersion, { platform: 'amp' }) }}

Note: The second argument is pageVersion - this is useful if the editors can preview an unpublished version from the admin, but one can pass null otherwise

AMP filter

Intro

XalokNext comes bundled with the AMP PHP Library, a library that automates the conversion of HTML to AMP HTML.

Using

Example: Pass the amp_filter option to the wf_cms_render_page function:

html
    {{ wf_cms_render_page(pageSlug, pageVersion, { platform: 'amp', amp_filter: true }) }}

Extending

XalokNext provides the wf_cms.amp.filter service that one can overwrite in the project to extend the AMP filter functionality.

The most common way of extending the AMP filter is to add custom AMP transform passes.

Example: Adding a custom transform pass:

php
<?php

namespace App\Bundle\CmsBundle\AMP;

use Lullabot\AMP\AMP;

class AmpFilter extends \Wf\Bundle\CmsBaseBundle\AMP\AmpFilter
{
    protected function setupAmp(AMP $amp)
    {
        parent::setupAmp($amp);
        
        $amp->passes[] = MyCustomTransformPass::class;
    }
}

Check out the AMP PHP Library passes or the ones provided by XalokNext to see how the transform passes work.

Image dimensions

The AMP HTML makes the images' width and height attributes mandatory. In order to find out the dimensions of the images, the AMP library needs to download the image first in order to read its dimensions. This can be very slow, especially if the image is hosted on S3 (as opposed to existing on the local hard drive).

In order to speed up this process, XalokNext implements a shortcut: if the name of the imagine filter follows the format image_filter_name__WIDTH_HEIGHT (e.g. image_500_300), XalokNext will take the width and the height from the name of the imagine filter, instead of downloading the image.

Note: This works only for mode: outbound filters, where the dimension of the thumbnail will always be the ones defined. For mode: inset, only either the width or the height will be the same, the other one will be calculated depending on the aspect ratio of the original image.

v7.2+AMP Scripts Dynamic Loading

Overview

This commit introduces a significant performance improvement for AMP script loading by implementing a module-based approach instead of full page rendering for script detection.

Problem Statement

Xalok was determining required AMP scripts by:

  1. Forwarding to page controller (wf_cms.controller.page:showAction)
  2. Rendering the complete page content
  3. Parsing the rendered HTML with DomCrawler to detect required AMP components
  4. Generating the appropriate script tags

Solution

Xalok now determines required AMP scripts by:

  1. Analyzing the page's module configuration
  2. Mapping modules to their required AMP scripts without rendering
  3. Using a configurable feature flag (amp_modules_to_scripts_enabled) to enable/disable the optimization

Configuration

You can enable this feature via configuration:

Set the parameter in your config (e.g., project.yml):

yaml
# project.yml
parameters:
    amp_modules_to_scripts_enabled: true  # Enable the optimization

Once enabled, your AMP pages will automatically use the optimized detection method. If the flag is set to false, the system will fall back to the original, full-rendering-based approach.

How It Works

When an AMP page is requested:

  • The system checks if the optimization feature is enabled
  • If enabled, it uses the AmpModulesToScriptsMapper to analyze the page's modules
  • It maps each module type (including custom ones) to its required AMP scripts
  • Only those scripts are included in the page’s output

If the feature is disabled, the system performs a full HTML render and parses it to determine which AMP scripts are needed — a much more resource-intensive approach.

Customization

You can override the script mapping logic for your own custom modules by extending the default mapper:

php
class CustomAmpModulesToScriptsMapper extends AmpModulesToScriptsMapper
{
    protected function getModuleScripts($primaryRolePath, $data)
    {
        switch ($primaryRolePath) {
            case ['video']:
                return ['amp-video', 'amp-analytics'];
            default:
                return parent::getModuleScripts($primaryRolePath, $data);
        }
    }
}

Register your custom mapper by overriding the service:

php
$container->getDefinition('wf_cms.amp.modules_to_script_mapper')
           ->setClass(AmpModulesToScriptsMapper::class);

Scripts for Modules

In the fixtures or in the admin settings of custom modules, you can specify AMP scripts with the ampScripts field. Check this skeleton commit for some examples