ALBIREO CMS
version: 2026.03.25

Получение записей в Albireo CMS

Хотя Albireo CMS — это система, работающая на файлах, она позволяет делать выборки записей с помощью обычных SQL-запросов, что ставит её в ряд CMS, изначально спроектированных для баз данных.

Запись — это любая страница сайта, которая представлена соответствующим php-файлом в PAGES_DIR.

Всё дело в том, что Albireo CMS использует кэш страниц в виде SQLite-таблицы file_info — это неотъемлемая часть системы. Поэтому в Albireo CMS нет необходимости дополнительно обсчитывать файлы, как это сделано во многих других Flat-File-System — здесь все данные получаются из базы.

Такой подход позволяет значительно снизить нагрузку на файловую систему сервера, а выборки записей делать привычными SQL-запросами.

Функция getPages()

В большинстве случаев будет достаточно использовать функцию getPages() для получения любых видов записей.

См. Полное описание функции getPages.

Albireo CMS не накладывает никаких ограничений на типы записей, поэтому вы сами решаете что и как именно будет выводиться на каждой странице.

Вот пример типового вывода всех последних записей сайта.

// Получить 10 последних опубликованных записей блога
$rows = getPages(limit: 10);

// Использование:
echo tpl(data: $rows['files'], tpl: TPL_DIR . 'one-column-3.php');
echo tpl(data: $rows['pagination'], tpl: TPL_DIR  . 'pagination1.php');

Функция getPages() возвращает массив с двумя элементами:

  • files c данными полученных записей
  • pagination с данными для пагинации

Обычно html-вывод осуществляется через встроенный tpl-шаблонизатор.

Получение с разными условиями

Используйте аргументы функции для получения разных видов записей.

Получение type: prompts

$rows = getPages(
    limit: 30,
    where: 'type = :type',
    order: 'file ASC',
    bindValue: [':type' => 'prompts'],
);

Получение записей выбранной метки/меток

// метка в виде массива
// strExplode, чтобы гарантированно получить массив из строки или массива

$tag = strExplode('php'); // в виде строки
// $tag = strExplode(['php']); // в виде массива

// Генерируем плейсхолдеры
$bind = \Pdo\PdoQuery::buildNamedPlaceholders($tag);

$rows = getPages(
    limit: 10,
    where: 'draft = 0 AND type = :type AND json_valid(tags) AND EXISTS (
        SELECT 1 FROM json_each(tags) WHERE value IN (' . $bind['string'] . ') COLLATE NOCASE
    )',
    order: $order,
    bindValue: [":type" => "blog"] + $bind['binds'],
);

Для меток удобней использовать функцию tagGetPages().

Получение записей выбранной рубрики/рубрик

// рубрика в виде массива
// strExplode, чтобы гарантированно получить массив из строки или массива

$category = strExplode('php'); // в виде строки
// $category = strExplode(['php']); // в виде массива

// Генерируем плейсхолдеры
$bind = \Pdo\PdoQuery::buildNamedPlaceholders($category);

$rows = getPages(
    limit: $limit,
    where: 'draft = 0 AND type = :type AND json_valid(category) AND EXISTS (
        SELECT 1 FROM json_each(category) WHERE value IN (' . $bind['string'] . ') COLLATE NOCASE
    )',
    order: $order,
    bindValue: [":type" => "blog"] + $bind['binds'],
);

Для меток удобней использовать функцию categoryGetPages().

Получение записей по подкаталогам

$rows = getPages(
    limit: 0, // все записи
    where: 'draft = 0 AND type = :type',
    order: 'subdirs ASC, file ASC, date_unix DESC',
    bindValue: [':type' => 'blog'],
);

Структура таблицы file_info

Таблица file_info хранит не все поля записей, а только избранные. Именно поэтому выборку можно сделать только для тех полей, которые определены в этой таблице. В большинстве случаев этого достаточно.

file TEXT,
slug TEXT,
slug_pattern TEXT, -- поле slug-pattern
method TEXT,
date_unix INT, -- поле date.unix
date_pub_unix INT, -- поле date-pub.unix
date TEXT, -- дата в формате Y-m-d H:i:s
type TEXT,
category TEXT, -- JSON
tags TEXT, -- JSON
draft INT, -- 1/0
rss INT, -- 1/0
sitemap INT, -- 1/0
favorite INT, -- 1/0
title TEXT,
header TEXT,
subdirs TEXT,
image_large TEXT, -- поле image-large
page_url TEXT, -- поле page-url
_order TEXT, -- поле order
_group TEXT, -- поле group
hierarchy TEXT,
info TEXT, -- поле _file_info
doc_menu_path TEXT,
file_mtime INT -- время последней модификации файла

Обратите внимание, что часть полей записей хранятся под другими именами в таблице. Это из-за конфликта синтаксиса SQL. Поэтому, если нужна выборка по полю group, то в запросе следует использовать _group и т.п.

В таблице метки (tags) и рубрики (category) хранятся в упакованном json-формате, поэтому запрос должен формироваться через json_each в виде подстроки WHERE:

// плейсхолдеры из массива $category
$bind = \Pdo\PdoQuery::buildNamedPlaceholders($category);
...

// WHERE в запросе
draft = 0
AND type = :type
AND json_valid(category)
AND EXISTS (
        SELECT 1
        FROM json_each(category)
        WHERE value IN (' . $bind['string'] . ') COLLATE NOCASE
    )

В SQLite COLLATE NOCASE делает регистронезависимый поиск, но только для английского языка. Это особенность SQLite.

Поля, которые работают как «флаг» (draft, rss и т.п.) преобразуются в числовому виду 1 или 0.

«Сырые» sql-данные. Все поля записи

Если нужно получить «сырые» данные от SQL-запроса, то используйте аргумент sqlResult:

$rows = getPages(
    limit: 30,
    where: 'type = :type',
    bindValue: [':type' => 'blog'],
    sqlResult: true
);

// отладка
pr($rows);

В обычном режиме getPages() получает записи из базы, но формирует итоговый массив с учетом всех полей записи. Поэтому в итоговом массиве будут все существующие поля записи, которые можно получить с помощью getPageData().

Например если у записи есть поле group: test, то его можно получить в теле файла:

pr(getPageData('group'));

Но, если нужно сделать выборку по этому полю, то следует использовать то, которое определено в file_info:

$rows = getPages(
    where: '_group = :val',
    bindValue: [':val' => 'test'],
);

Добавление своих полей в file_info

Добавление своих полей в таблицу file_info происходит через конфигурационный файл file-info-fields.php. Вот примеры полей:

return [
    [
        // пример текстового поля
        'field' => 'group-favorite', // поле в файле записи
        'key' => 'my_group-favorite', // ключ в базе — лучше, если начинается с my_
        'keyType' => 'TEXT', // тип ключа в формате запроса SQL
        'default' => '', // дефолтное значение для базы
        'fn' => fn($v) => $v, // функция через которую пропускаем обработку $val
    ],

    [
        // пример check-поля
        'field' => 'comments',
        'key' => 'my_comments',
        'keyType' => 'INT',
        'default' => 0,
        'fn' => fn($v) => checkStr($v) ? 1 : 0,
    ],
];

После того, как новые поля добавлены, необходимо сбросить старый кэш. Это можно сделать изменив любую страницу сайта, либо вручную удалив файл service/storage/filesinfo.sqlite.

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

ВАЖНО! Добавлять новое поле есть смысл только для тех задач, когда по этому полю нужна sql-выборка! Если поле просто используется на странице, то ничего создавать не нужно — оно и так доступно через getPageData().