Сайт вебмастера

Что такое Мультисайт?

15-05-2024Время чтения ~ 6 мин.Albireo Framework / CMS 298

Несколько неожиданно даже для меня, оказалось, что Albireo CMS может работать как мультисайт (multisite). Мультисайт — это возможность использовать единый «движок» системы для раздельных сайтов. Из самых популярных CMS, которые поддерживают мультисайтинг стоит отметить Drupal и WordPress (WPMU).

Интересно, что в ТЗ по Albireo CMS у меня изначально отмечен пункт, где сказано, что система должна поддерживать несколько сайтов на одном «ядре». Именно в этом направлении я и вёл разработку, но как базовую концепцию мультисайтовости я не рассматривал. К ней я подошёл эволюционным путём, изучая собственные потребности.

Зачем нужен мультисайтинг? Самый простой пример — разные языковые версии сайта. Как показывает опыт, лучше всего иметь отдельную копию сайта для каждого языка, чем плясать с бубном в рамках одного сайта. В зависимости от потребности, языковые версии могут иметь одно и тоже «ядро», единый шаблон, может какие-то модули, расширения и т.п.

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

Единое ядро упрощает обновление и поддержку всех таких сайтов. Даже если это всего три сайта, то это уже упрощает задачу.

Сам по себе мультисайтинг строится вокруг нескольких базовых вещей.

Основной — это настройка поддоменов/подкаталогов. Обычно это делается в .htaccess, где нужно прописать специальные инструкции для того, чтобы организовать перехват адресов поддоменов. Стоит отметить, что не каждый хостинг может это позволить, поэтому настройка поддоменов не самая тривиальная задача.

Корень проблемы в том, что раньше хостинги не позволяли просто создавать поддомены. Всё крутится вокруг Apache, поэтому многое нужно было писать ручками. Сейчас всё намного проще — механизм отработан — в панели управления указываем создание любого поддомена и всё сразу работает.

Есть два варианта: поддомен может создаваться как отдельный сайт со своими каталогами. Второй вариант — поддомен в каталоге домена. В этом случае по сути получается, что любой подкаталог превращается в домен третьего уровня: site.com/site1 будет эквивалентен site1.site.com. Но, опять же, всё зависит от хостинга.

Главное здесь в том, что URL-адрес любого сайта будет соответствовать отдельному каталогу либо система будет сама решать как именно интерпретировать такие адреса.

В Drupal есть каталог sites, который будет содержать все сайты. Здесь можно указать конфигурацию и разместить какие-то особенные файлы конкретного сайта. Таким образом можно изолировать сайты друг от друга. Скажем, указать разные базы для каждого сайта.

В WordPress (точнее WPMU — MultiUser) схема немного другая. В ней всё завязано на префиксы. То есть единая база, но для каждого сайта добавляется префикс вида «wp1_», «wp2_» и т.д. Таким образом можно использовать одну базу, но с индивидуальными таблицами в базе.

Конечно же, здесь возникает масса ограничений. Например не каждый плагин позволяет работать в таком режиме. Если CMS использует фиксированный каталог для модулей, то шаблоны, плагины и т.п. может устанавливать только «суперадмин».

Админ-панель также усложняется, поскольку её уже нужно знать с каким именно сайтом производятся действия.

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

В Albireo CMS я сразу сделал одну вещь, которая позволила получить «идеальный» мультисайт — я сразу сделал так, что все данные сайта хранятся в одном каталоге. Изначально (я об этом писал ранее), я выделил system для ядра, storage для баз и кэша, admin для админки, website непосредственно для самого сайта и uploads для загрузок.

Предполагалось, что admin и website имеют идентичную структуру и это позволяет создавать любые другие аналогичные (под)сайты.

Потом я понял, что storage — это всё-таки уровень конкретного сайта, потому что когда я сделал новый сайт, то оказалось, что их базы и их кэш должны разделяться. Поначалу я немного поигрался с префиксом, но понял, что это глупость и просто перенес storage в website.

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

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

title: Albireo CMS
description: Albireo CMS
slug: <?= ALBIREO_ADMIN_NAME ?>
user-level: admin
type: system
layout: full-width.php
headers: -
footers: -
head-meta[robots]: noindex
parser: -
compress: -
use.imfont: +
use.alpine: +
css.style: 
css.theme: berry.css

**/

albireo_admin_albireo();

# end of file

Это позволяет ему, в случае необходимости, подправить визуальный вывод админки и уровни доступа с помощью полей записи. Кроме этого он может совершенно спокойно добавить любые свои страницы в админку. Так же есть отдельный конфиг-файл, где можно указать разные настройки. То есть суть в том, что у пользователя есть возможность управлять админкой. Если же она ему не нужна, то можно просто удалить весь каталог страниц. Обновление админки происходит вместе с обновлением system, то есть для пользователя совершенно прозрачно.

Но главное, что админка работает только со своим сайтом. А сайт работает со своей конфигурацией: со своими юзерами, базами, шаблонами и т.д.

Последним «под раздачу» попал каталог uploads — он был в корне сайта, но очевидно, что если сайты должны быть изолированы, то у них должны быть и разные загрузки. Таким образом получилась очень простая структура каталогов:

system 
   functions
   psr4
   widgets
   install

website
   config
   service
   snippets
   pages
   templates
   uploads

То есть вся «неизменная» часть размещена в system, остальное в website. Если мы хотим сделать новый сайт, то нужно просто сделать копию каталога website.

В корневом index.php указывается:

// имя каталога web-сайта
define('FRONT_NAME', 'website'); 

Это значит, что когда идёт обращение к основному домену, будет использован сайт website.

По сути это создаёт полные копии для адресов site.com и site.com/website (или website.site.com). Так происходит из-за того, что в Albireo CMS каждый сайт по сути есть физический каталог на сервере. То есть в отличие от других систем, где нужны танцы с бубном вокруг .htaccess, здесь вообще ничего не нужно делать — система принципиально не различает все эти «чудеса» и поэтому работает с каждым сайтом абсолютно одинаково.

Чтобы исключить дубли адресов основного сайта и его подкаталога, то в специальном файле website/redirects.php указываются 301-редиректы с подкаталога на основной домен.

redirectPatterns([
    '(https|http)://site.my/website' => '$1://site.my',
]);

Для остальных сайтов этого уже не нужно делать.

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

Для этого у сайта создаётся constants.php, где определяются константы с путями до всех каталогов.

Сама система формирует пути таким образом:

if (!defined('COMMENTS_DIR')) define('COMMENTS_DIR', BASE_DIR . 'comments' . DIRECTORY_SEPARATOR);

Если мы захотим разместить комментарии на уровень выше, то в website/constants.php достаточно разместить:

define('COMMENTS_DIR', LEVEL_UP_DIR. 'comments' . DIRECTORY_SEPARATOR);

И это касается практически всех каталогов каждого сайта: шаблоны, виджеты, кэш, базы, записи, общие ресурсы шаблонов, каталога uploads, и даже каталога для Composer.

Такой подход позволяет создавать не только изолированный мультисайт, но и решать какие ресурсы могут быть общими.

Всё это возможно из-за того, что изначальная идея об изолировании каждого сайта, оказалась верной.


Слава Украине! Смерть рашистам!

Похожие записи
Комментарии (1) RSS
1 Віктор 2024-05-25 08:22:00

Концептуальна стаття. Однозначно корисна, яка позбавила мене від ідеї об'єднання окремих каталогів в один, для уніфікації роботи над мульти-тематичними розділами. Альбірео був цікавим саме для експериментальної роботи, коли ізоляція сайтів формувалася через просте дублювання каталогів.

Як на мене, constants.php має стати ключовою ідеєю перебудови вже зробленого, хоча хоронити свої ідеї буде трохи боляче.

Адмінка важлива частина, безперечно, але (на мою думку) лише при необхідності розділення прав доступу. Чи буде вона в нових релізах? (сліди такого намагання були в ранішньому коді).

Оставьте комментарий!