Albireo* Framework

Современный ✸ Быстрый ✸ Компактный PHP-фреймворк с админ-панелью
✸ ✸ ✸
✸ ✸ ✸
Установка Описание файлов и каталогов Создание и настройка страниц Адреса страниц Размещение страниц в каталоге pages Парсер и сжатие текста HTML-шаблон вывода Конфигурация Параметры страниц по умолчанию Сниппеты Генератор статичного сайта Админ-панель Демо-доступ к админ-панели Ограничение доступа пользователей Создание документации Отправка форм (POST) Отправка форм (AJAX и произвольный REST) Роутинг по паттерну URL Параметры страницы в виде массива Как добавить данные в секцию HEAD и BODY Основные константы Файлы инициализации Кэширование Файл sitemap.xml Шаблонизатор Произвольный каталог записей Albireo Framework как учебный проект

Установка

1. Загрузите архив Albireo Framework и распакуйте на свой сервер.

Скачать Albireo Framework или проект на GitHub.com →

2. Наберите в браузере адрес сайта. Автоматически будет создан файл .htaccess, который обеспечивает поддержку ЧПУ.

3. Вы увидите страницу приветствия Albireo.

Примечание. Если вы переносите сайт на другой поддомен, то удалите файл .htaccess — он будет создан автоматически.

[*] Альбирео — это одна из самых красивых двойных звёзд. Расположена в созвездии Лебедя и хорошо видна даже в скромные телескопы. Главный компонент — оранжевый гигант в 100 раз больше радиуса Солнца. Второй компонент — голубая звезда размером в 3☀.
Albireo Framework — бесплатный и открытый проект для любого использования, включая коммерческое. Если он вам понравился, вы можете поставить «звёздочку» на GitHub.com. Задать вопрос вы можете там же в форуме Albireo. Если есть возможность, вы можете оказать материальную поддержку автору проекта. Если вы готовы стать спонсором проекта (с размещением логотипа и ссылки) напишите мне через Twitter или любым другим способом.

Описание файлов и каталогов

Каталог albireo содержит ядро и не требует изменений (можно обновлять поверх старой версии).

Каталог albireo-data содержит все пользовательские данные: страницы, файлы конфигурации, html-разметку (шаблоны), сниппеты для быстрой вставки и т.д.

В каталоге assets размещаются общедоступные файлы: css, images и т.д. Вы можете использовать его по своему усмотрению. По умолчанию в Albireo включена библиотека Berry CSS, которую вы можете заменить на любой другой вариант. Здесь Berry используется только в качестве демонстрации (а также в Albireo Doc).

Каталог uploads используется для загруженных файлов, например изображений.

Файл index.php представляет собой точку входа фреймворка. В нём формируются пути и базовые константы, необходимые для работы Albireo.

Файл static.php используется для запуска генератора статичного сайта. Он создаст каталог albireo-static с готовыми html-файлами вашего сайта. Они могут быть загружены на рабочий сервер.

Создание и настройка страниц

Все страницы сайта хранятся в каталоге albireo-data в виде отдельных php-файлов. Имена файлов могут быть произвольными. Если имя файла начинается с символа _, то Albireo будет его игнорировать.

Каждый файл имеет такую структуру:

<?php if (!defined('BASE_DIR')) exit('No direct script access allowed');
/**

ключ1: значение
ключ2: значение
ключ3: значение

**/
?>

текст страницы

Первая php-строчка служит для защиты от прямого вызова файла.

Служебная часть страницы размещается в блоке php-комментариев /** **/ в виде параметров ключ: значение. Ключи могут быть произвольными и использоваться для управления выводом.

Следующие ключи используются Albireo на уровне «ядра»:

slug: адрес страницы
slug-static: имя файла при генерации html-файла
slug-pattern: дополнительный паттерн адреса
method: http-метод страницы (для роутинга)
parser: парсер текста
compress: признак сжатия html-кода
protect-pre: защитить содержимое PRE и CODE
layout: шаблон вывода
init-file: файл инициализации
text-function: функции для постобработки html-кода
content-only: обработка файла страницы отдельно от layout-шаблона

А эти ключи используются в шаблоне main.php:

title: титул записи
description: описание
body: атрибуты BODY, например class и/или style
html-lang: язык страницы — по умолчанию ru
meta[]: атрибуты meta (см. «Параметры страницы в виде массива»)
head[]: произвольные данные в HEAD
link[]: атрибуты link
lazy[]: произвольные данные вперед закрывающим BODY
Обратите внимание, что в ключе после символа : следует добавить пробел. Например slug: about — верно, а slug:about — ошибка. Это позволяет использовать в ключах символ :, например: meta[og:title]: Заголовок страницы.

Адреса страниц

В поле slug указывается адрес, по которому будет доступна страница. Для главной страницы следует использовать /. Slug указывается относительно сайта. Например

slug: form

сделает доступной страницу по адресу ваш-сайт/form. Такой вариант:

slug: form/contact/about

по адресу ваш-сайт/form/contact/about

Или даже так:

slug: form.html

по адресу ваш-сайт/form.html

Таким образом вы можете формировать произвольные адреса для любой страницы сайта.

Если поле slug не указывать, то оно будет автоматически сформировано из имени файла. Например для файла contact.php ссылка будет ваш-сайт/contact.

Если у нескольких страниц slug совпадает, то Albireo подключит первую по алфавиту.

404-страница

Файл страницы 404.php является предопределённым и выводится в случаях, когда не найдена страница для вывода.

Защита от XSS-атаки

В Albireo встроена защита от XSS-атак, при которой вредоносный код может передаваться через входящий URL.

Защита базируется на фильтрации символов, которые как правило используются в атакующем коде, но нетипичны для любого адреса. Поэтому в Albireo не следует использовать в адресах страниц следующие символы:

< > " ' ( { [

Размещение страниц в каталоге pages

При желании файлы страниц можно разместить в каталоге albireo-data/pages. Он работает точно также, как и основной каталог albireo-data.

albireo-data/
    pages/
        page1.php
        page2.php

    home.php
    about.php

В pages можно использовать произвольную вложенность каталогов. Адреса страниц в pages определяются также, как и в основном каталоге — по полю slug.

Если поле slug у страницы не указано, то оно будет автоматически совпадать с именем файла с учётом вложенности в pages.

Вот пример того, как Albireo автоматически присвоит slug:

albireo-data/
    pages/
        install/
            page1.php → install/page1
            page2.php → install/page2
            
        update/
            page1.php → update/page1
            page2.php → update/page2

    home.php  → home
    about.php → about

Используйте pages, если сайту требуется группировка файлов по каталогам.

Парсер и сжатие текста

Текст страницы может быть обработан после формирования. В комплект Albireo включен парcер Simple из MaxSite CMS. Он задаётся в параметре parser:

parser: simple

Чтобы отключить парсер (если он включен по умолчанию в конфигурации) можно указав - (минус):

parser: -
Парсер текста — это обычная php-функция, которая принимает и возвращает текст. Имя файла (без расширения «.php» в каталоге albireo/lib) совпадает с именем функции.

Если вы используете html-тэги PRE и CODE, то можно их содержимое преобразовать в html-сущности. Для этого используется ключ protect-pre:

protect-pre: 1

В text-function можно обработать html-код страницы через любую php-функцию, которая принимает и возвращает строку. Можно указать несколько функций через пробел.

text-function: trim myParser

По умолчанию Albireo пропускает через парсеры полный html-код, включая layout-шаблон. При необходимости, если возникают проблемы с парсером в секции HEAD, используйте обработку текста только для файла страницы. Для этого в параметрах страницы достаточно указать:

content-only: 1

Для сжатия html-кода также используется библиотека из MaxSite CMS, которая включается через параметр compress с любым (true) значением:

compress: 1

Сжатие работает для всего итогового html-кода страницы сайта.

HTML-шаблон вывода

Шаблоны вывода размещаются в каталоге albireo-data/layout и представляют собой обычные php-файлы с html-разметкой и php-кодом.

Поскольку шаблон вывода всегда необходим для работы Albireo, то он является обязательным. Шаблон по умолчанию задаётся в конфигурационном файле.

Файл main.php содержит html-разметку, внутри которой происходит вывод файла страницы.

Для вывода данных используется функции getPageData('ключ') и getPageDataHtml('ключ'). Первая возвращает значение ключа как есть, а вторая обрабатывает его для корректного вывода в HTML. Это необходимо например для вывода title и description.

В шаблоне может использоваться функция getConfig('ключ'), которая возвращает значение из текущей конфигурации сайта. Например url-путь к каталогу assets.

Файл шаблона empty.php не содержит html-разметки и возвращает «чистый» код страницы. Этот шаблон используется для формирования Ajax-запросов или когда нужно сформировать страницу полностью в своём файле.

Шаблонов может быть несколько и если страница использует вариант, отличный от дефолтного, то он указывается в виде ключа layout:

layout: main-about.php

При необходимости шаблон вывода может находится в произвольном каталоге. В этом случае он указывается относительно каталога данных (albireo-data):

layout: templates/about/main.php

Конфигурация

Конфигурация хранится в каталоге albireo-data/config. Есть два файла.

Первый config.php содержит данные для обычного вывода:

return [
    'assetsUrl' => SITE_URL . 'assets/', // url-путь к assets
    'layout' => 'main.php', // шаблон вывода по умолчанию
];

Второй файл config-static.php используется в режиме генератора статичного сайта.

Параметры страниц по умолчанию

В конфигурации можно задать дефолтные значения для всех страниц сайта. Для этого используется ключ defaultPageData, которая представляет собой массив.

return [
    'assetsUrl' => SITE_URL . 'assets/', // url-путь к assets
    'layout' => 'main.php', // шаблон вывода по умолчанию

    // дефолтные данные страниц
    'defaultPageData' => [
        'parser' => 'simple', // парсер simple
        'compress' => 1, // сжатие html-кода
        'protect-pre' => 1, // защитить содержимое PRE и CODE
    ],
];

Сниппеты

В сниппетах удобно хранить небольшие фрагменты html/php-кода, например счётчики, код рекламы и т.д. Сниппеты располагаются в каталоге albireo-data/snippets каждый в своём файле.

Вывод сниппета в тексте страницы выполняется с помощью функции snippet('сниппет').

<?php snippet('twitter') ?>

В сниппет можно передать данные — они указываются во втором параметре функции.

<?php snippet('content', 'text text text') ?>

В файле сниппета будет автоматически доступна переменная $data с переданными данными.

Генератор статичного сайта

Если на сайте не используется динамический контент (или не работает PHP на сервере), то Albireo поможет создать страницы в виде статичных html-файлов. Их можно будет загрузить на сервер, например на github.io.

Вначале следует задать конфигурацию в файле config-static.php.

return [
    // каталог хранения готовых статичных страниц
    'staticDir' => BASE_DIR . 'albireo-static' . DIRECTORY_SEPARATOR,
    'assetsUrl' => 'assets/', // путь к assets 
    'layout' => 'main.php', // шаблон сайта
    'afterCopy' => ['assets'], // после генерации скопировать каталоги
];
Следует учитывать, что при этом не используется конфигурация из config.php. Это позволяет задавать разные варианты вывода для статичного и динамичного сайтов (например использовать разные шаблоны вывода layout).

В данном случае файлы будут сохранены в каталоге albireo-static. Если его нет, то он будет автоматически создан.

Перед началом генерации этот каталог будет полностью очищен.

Параметр afterCopy позволяет указать каталоги, которые будут скопированы в результирующий каталог после генерации файлов. По умолчанию указан каталог assets. Таким образом в итоговом каталоге albireo-static окажутся все файлы для загрузки на удалённый сервер.

Также обратите внимание на расположение каталога assets. В режиме генерации невозможно определить адрес текущего сайта, поэтому укажите корректный путь в параметре assetsUrl (лучше относительный).

При необходимости в файле static.php можно указать и другие параметры сайта в режиме генерации.

Запуск генератора осуществляется через командную строку (используйте терминал операционной системы):

php static.php

Итоговый файл страницы указывается в параметре slug-static. Если его нет, то используется обычный slug с добавлением расширения .html.

Если нужно исключить страницу из генерации (например в нём используются формы), то в slug-static указывается - (минус):

slug-static: -

Если в slug или slug-static указывается вложенность каталогов (с помощью /), то Albireo повторит эту структуру в виде подкаталогов.

slug-static: doc/install/step1.html

В этом примере будет создан файл albireo-static/doc/install/step1.html

В Albireo используется константа STATIC_EXT, которая специально предназначена для указания расширения файла в режиме генерации. В обычном режиме она равна пустой строке, а в режиме генерации .html. Например в тексте страницы используется ссылка:

text text <a href="<?= SITE_URL ?>about">link</a>

В обычном режиме ссылка будет равна about. В режиме генерации страница about будет уже файлом about.html, что сделает такую ссылку нерабочей. В таких случаях, следует указывать STATIC_EXT:

text text <a href="<?= SITE_URL ?>about<?= STATIC_EXT ?>">link</a>

В режиме статичной генерации ссылка получится about.html.

Админ-панель

Админ-панель доступна по адресу http://ваш-сайт/admin.

C помощью админ-панели можно:

Для работы с админ-панелью следует создать список пользователей. Он располагается в файле admin/config/_users.php.

Сейчас в нём закомментированные примеры, которые можно использовать для тестирования на localhost. На рабочем сайте следует изменить пароли на другие.

Добавьте пользователей и укажите их уровень доступа:

'1' => [ // уникальный ID
    'nik' => 'Admin', // ник для отображения
    'username' => 'admin', // логин
    'password' => '123456', // пароль
    'expiration' => mktime(0, 0, 0, 1, 1, 2030), // дата окончания
    
    // уровень доступа 
    // admin — разрешение на доступ в админ-панель
    // admin-change-files - разрешение на изменение файлов
    'level' => ['admin', 'admin-change-files'], 
],

После этого достаточно набрать http://ваш-сайт/admin в браузере и будет предложена форма, где следует ввести указанные логин и пароль. Если они корректные, то вы получите доступ к админ-панели.

Вместо admin/config/_users.php вы можете создать его копию как config/users.php — он будет иметь приоритет перед первым. Это позволит обновлять админ-панель Albireo не боясь затереть собственную конфигурацию админ-панели.

Демо-доступ к админ-панели

Вы можете посмотреть как выглядит админ-панель в демо-режиме. Для входа используйте данные:

В демо-режиме нельзя изменять файлы.

Ограничение доступа пользователей

Albireo поддерживает разделение прав доступа пользователей. Например когда необходимо скрыть контент для незарегистрированных посетителей.

Для этого создаются пользователи в конфигурации админ-панели, где указываются их уровень доступа. Например доступ pages разрешает просмотр всей страницы — если его нет, то будет выведена страница «Доступ запрещён». Чтобы получить доступ к записи нужно будет пройти авторизацию.

Либо можно ограничить только часть контента страницы. Например первая часть будет доступна всем посетителям сайта, а остальная — только после оплаты (регистрации и авторизации с доступом secret content).

Чтобы использовать данные возможности, в Albireo включены файлы pages/demo-access1.php и pages/demo-access2.php, где вы сможете посмотреть несложный PHP-код и взять эти файлы за основу.

Создание документации

Albireo Doc — специально предназначена для тех разработчиков, которые хотят создать документацию для своего проекта. В комплект Albireo входит layout-шаблон doc.php, который организует вывод боковой колонки и готовый дизайн для типового сайта документации.

Управлять Albireo Doc можно также, как и другими страницами, включая доступ через админ-панель. Точно также вы можете создавать статичные html-файлы для загрузки на сторонний сервер, например на GitHub.com.

Все файлы для документации включены в дистрибутив Albireo. Вы можете посмотреть в живую как это выглядит (там же приведено описание).

Отправка форм (POST)

Albireo поддерживает отправку произвольного POST-запроса.

Например на странице ваш-сайт/form размещается типовая html-форма отправки:

slug: form
...

<form method="post> ... форма ...

Отправка будет происходить на этот же самый url-адрес. Чтобы его перехватить, делается ещё одна страница (например form-post.php), с тем же slug, но ещё указывается http-метод отправки:

slug: form
method: POST
...

Страница для приёма post-запроса

Таким образом Albireo отследит slug и method и подключит необходимый файл.

Отправка форм (AJAX и произвольный REST)

Поле страницы method может быть произвольным. Но поскольку стандартно браузеры поддерживают только POST и GET-методы, то для отправки любого другого в форме указывается скрытое поле _method.

<form onsubmit="sendAjax(this); return false;">
	<input type="hidden" name="_method" value="AJAX"> 
	...

В данном примере произойдет отправка данных по POST, но поскольку в форме есть поле _method, то Albireo будет использовать уже его.

Соответственно в файле обработчике (например form-ajax.php) указывается:

slug: form
method: AJAX
...

Обработка запроса

Если это будет реальный Ajax-запрос, то у такой страницы нужно указать layout: empty.php, чтобы исключить вывод ненужного html-кода.

Полный код этих примеров вы найдёте в файлах страниц: form.php, form-post.php и form-ajax.php. Они будут доступны по адресу ваш-сайт/form как демо-пример.

Роутинг по паттерну URL

Параметр slug «жестко» определяет адрес страницы. Например:

slug: page

будет работать только с адресом ваш-сайт/page.

Когда стоит задача сделать доступной страницу по разным адресам, то используется дополнительный параметр slug-pattern. Он проверяется сразу после slug (при несовпадении текущему URL).

slug: page
slug-pattern: hello

Данный пример сделает доступным страницу по адресам ваш-сайт/page и ваш-сайт/hello.

В slug-pattern можно использовать регулярное выражение, в котором указать паттерн соответствия URL. Например:

slug: page
slug-pattern: (hello|welcome)

сделает страницу доступной по адресам ваш-сайт/page, ваш-сайт/hello и ваш-сайт/welcome. Другие примеры:

любой символ
slug-pattern: page/(.*?)
ваш-сайт/page/123 | ваш-сайт/page/abc | ваш-сайт/page/a_b-c2 

только числа
slug-pattern: page/([0-9]+)
ваш-сайт/page/123

только буквы
slug-pattern: page/([a-zA-Z]+)
ваш-сайт/page/abc

буквы и/или цифры
slug-pattern: page/([a-zA-Z0-9]+)
ваш-сайт/page/abc | ваш-сайт/page/123 | ваш-сайт/page/123abc

включить все «page/*», за исключением «page/about» и «page/contact»
slug-pattern: page/(?!about)(?!contact)(.*)

Поскольку такой роутинг не имеет смысла для статики, то slug-pattern не учитывается при генерации статичного сайта.

Параметры страницы в виде массива

В некоторых случаях для страницы нужно указать параметры вида:

key[index1]: value
key[index2]: value
key[index3]: value

Например для разметки OpenGraph:

meta[og:type]: website
meta[og:title]: Заголовок
meta[og:description]: Описание
meta[og:url]: Адрес
meta[og:site_name]: Название сайта 

Для вывода таких данных в шаблоне используйте код в секции HEAD:

<?= implode(getKeysPageData()) ?>

По умолчанию используются ключ и html-тэг meta. На выходе получится:

<meta property="og:type" content="website">
<meta property="og:title" content="Заголовок">
<meta property="og:description" content="Описание">
<meta property="og:url" content="Адрес">
<meta property="og:site_name" content="Название сайта">

Вы можете использовать любые ключи и любой формат вывода.

link[canonical]: Адрес

В шаблоне:

<?= implode(getKeysPageData('link', '<link rel="[key]" href="[val]">')) ?>

В итоге получится:

<link rel="canonical" href="Адрес">

Можно использовать спецзамены:

Например:

meta[og:title]: [page-title]
meta[og:description]: [page-description]
meta[og:url]: [site-url][page-slug]

Как добавить данные в секцию HEAD и BODY

Если стоит задача добавить небольшие произвольные данные в секцию HEAD (например url-адрес, meta-данные и т.д.), то можно предусмотреть поле head[уникальный индекс]:

head[1]: <meta name="robots" content="noindex, nofollow">
head[2]: <script src="..."></script>
head[3]: <link rel="stylesheet" href="...">

В шаблоне вывода в секции HEAD используется такой php-код:

<?= implode(getKeysPageData('head', '[val]')) ?>

Обратите внимание, что у каждого поля head[] нужно указывать произвольный уникальный индекс. При их совпадении Albireo будет использовать последний. В тех случаях, когда индекс не используется, можно его не указывать (Albireo автоматически создаст уникальный числовой индекс):

head[]: <meta ...
head[]: <script ... 
head[]: <link ...

Аналогичным образом можно организовать вывод данных в конце BODY или другом месте шаблона. По умолчанию в шаблоне main.php можно использовать поле lazy[], которое выводит данные перед закрывающим BODY.

Основные константы

Основной файл index.php автоматически создаёт php-константы, которые можно использовать в своём коде:

При необходимости их можно переопределить. Для этого в главном каталоге нужно создать файл config.php, где и указать свои данные.

define('SITE_HOST', 'mysite'); // хост сайта
define('SITE_PROTOCOL', 'https'); // его протокол
define('SITE_URL', 'https://mysite/'); // полный адрес

Таким образом можно поменять расположение каталогов по умолчанию без правки файлов Albireo.

Файлы инициализации

Если стоит задача подключить php-файл перед подключением шаблона страницы, то используется ключ init-file. Например:

init-file: _functions.php

Файл указывается относительно каталога данных (albireo-data). Если такой файл размещается среди файлов страниц, то его имя должно начинаться с символа подчеркивания _. В этом случае Albireo не будет его обрабатывать как страницу.

Произвольный php-файл также можно подключить в конфигурации в ключе functions.

...
'functions' => DATA_DIR . 'mylib/functions.php',
...

Это файл будет подключён перед обработкой шаблона для всех страниц сайта.

Кэширование

Для оптимизации своей работы Albireo использует кэш в виде файлов pagesinfo.txt и snapshot.txt в каталоге albireo/cache. Кэш обновляется автоматически, как только будут изменения в каталоге данных.

Если файлы кэша не создаются, то проверьте, чтобы у каталога albireo/cache были права на запись (обычно это 777).

Для разработчиков есть возможность отключить использование кэша в файле конфигурации:

... 
    'noCache' => true,
...

Обычно это используется в режиме отладки кода.

Файл sitemap.xml

Файл sitemap-xml.php автоматически формирует xml-карту сайта по адресу http://ваш-сайт/sitemap.xml (см. пример).

Для исключения страницы из sitemap.xml нужно указать:

sitemap: -

Указать приоритет и частоту обновления страницы можно так:

sitemap-changefreq: weekly
sitemap-priority: 0.9

Шаблонизатор

С помощью шаблонизатора можно вынести произвольные части страниц в отдельные файлы и работать с ними независимо. Особенно эффективен шаблонизатор для повторяющихся блоков, которые имеют небольшие различия.

Например есть блок, который используется несколько раз на странице, но меняется только текст. Создадим файл этого блока, например _tpl-block.php.

<div class="t-center pad30 bg-gray100">
    <h1>{{ $header }}</h1>
    <p>{{ $desc }}</p>
</div>

В тексте страницы используется функция tpl(файл шаблона, данные):

<?php
    $data['header'] = 'Заголовок';
    $data['desc'] = 'Описание';
?>

<?= tpl(DATA_DIR . '_tpl-block.php', $data) ?>

Либо так:

<?= tpl(DATA_DIR . '_tpl-block.php', ['header' => 'Заголовок', 'desc' => 'Описание']) ?>
Файл нужно указывать с полным именем.

В файле шаблона можно использовать обычный php-код, а также специальные замены.

В дистрибутиве Albireo Framework в каталоге pages/sample размещены файлы tpl.php и _tpl-block.php, демонстрирующие работу шаблонизатора.

Произвольный каталог записей

При необходимости можно разместить файлы страницы в отдельном произвольном каталоге, например my-pages. Для этого в файле конфигурации следует использовать ключ dirsForPages:

'dirsForPages' => [BASE_DIR . 'my-pages'],

Можно указать несколько каталогов:

'dirsForPages' => [BASE_DIR . 'my-pages', BASE_DIR . 'user-pages'],
Обратите внимание, что каталоги указываются в полном виде. В данном случае BASE_DIR указывает на корень сайта.

Не нужно указывать каталог albireo-data, а также вложенные каталоги. В следующем примере второй каталог лишний).

'dirsForPages' => [BASE_DIR . 'my-pages', BASE_DIR . 'my-pages/docs'],

Такие каталоги следует рассматривать как аналоги albireo-data/pages, где можно размещать только файлы записей, но не конфигурацию и прочие служебные файлы.

Albireo Framework как учебный проект

Код фреймворка достаточно простой и мне хотелось показать его особенности для начинающих php-программистов. Именно поэтому исходные файлы Albireo сопровождаются большим количеством комментариев, объясняющих каждую строчку или блок кода.

Вы можете использовать Albireo Framework в учебных целях или взять его за основу своего будущего проекта.

Подробное описание программной части Albireo было приведено в моём telegram-канале.

© Albireo Framework, 2020, MAX