В данной статье я бы хотел рассказать о разрабатываемой мной системе управления контентом Zoia, написанной на Javascript. Это мой side-project, не связанный с основной работой, который я разрабатываю и развиваю в свободное время. Есть мнение, что каждый веб-разработчик должен рано или поздно написать свою собственную CMS, а кто-то даже и не одну :-)

TL;DR: demo.zoiajs.org, панель администратора (логин: admin, пароль: password), Github, лицензия MIT

Свершившийся факт: Javascript сейчас везде, его можно использовать не только на стороне клиента, но и на стороне сервера, а также в микроконтроллерах, автомобилях, смартфонах — одним словом, практически в любой области. Но «традиционной» для JS областью был и остается веб, где этот язык программирования оброс целым зоопарком библиотек, паттернов, утилит и фреймворков. Разобраться во всем этом достаточно сложно, а иногда все, что требуется — это сделать достаточно простой сайт, которым можно будет в случае необходимости быстро управлять: добавлять и редактировать контент, меню навигации и т.д.

Для подобных задач есть много CMS, написанных на PHP (некоторые из которых я использовал в работе, такие, GetSimple CMS), но я не встречал ни одной реактивной CMS, полностью написанной на JS и использующей Mongo в качестве БД (напишите, пожалуйста, в комментариях, если такое есть, а я пропустил). После знакомства с React и Marko уже не хочется возвращаться в суровый мир jQuery, и так родилась Zoia. Кстати, это уже вторая версия, первая работала как раз по-старинке (сейчас не поддерживается и не обновляется).

На текущей стадии разработки удалость реализовать следующее:

  • Zoia разрабатывается на Javascript — как на стороне сервера, так и на клиенте
  • Имеет модульную архитектуру, имеется возможность расширить функционал за счет добавления новых модулей
  • Распределенная архитектура: API на Fastify+Mongo, панель администратора на React+Redux, веб-сервер для userspace на Fastify+Marko — все это можно установить на различные серверы
  • Многоязычность «из коробки», уже есть английский и русский языки, можно добавлять любое количество языков — используется Lingui.
  • Большое количество вспомогательных компонентов, библиотек и утилит: для генерации форм, динамических таблиц (пока только в панели администратора), авторизации и т.д.
  • Сборка осуществляется при помощи Webpack
  • Редактирование контента: можно использовать несколько шаблонов дизайна (например, для различных страниц); есть опция выбора способа управления контентом: либо редактор WYSIWYG (используется CKEditor 5), либо редактор кода HTML (ACE Editor соответственно); при сохранении происходит оптимизация контента (минификация кода и применение типографа) — при выставлении соответствующих опций; существует возможность структурировать дерево категорий, в которых находятся страницы, и использовать «хлебные крошки»; есть «загрузчик» картинок (реализация как для CKEditor, так и для ACE)
  • Управление пользователями: добавление любого количества пользователей, возможность редактировать их профиль, устанавливать пароль и статус
  • Управление навигацией: удобное управление деревом навигации, возможность добавления «подменю»
  • Готовые скрипты для сборки, подготовки конфигурации systemd, NGINX и т.д.

Немного об архитектуре. Как я уже сказал выше, система состоит из API (обслуживает запросы к базе, обработку данных), панели администратора (работает как SPA, использует роутинг на стороне клиента, разработана с использованием React+Redux) и пространства пользователя (изоморфная архитектура, разработано с использованием Marko, рендеринг осуществляется на стороне сервера с последующей регидрацией на клиенте). Панель администратора обращается к API прямо со стороны клиента, веб-сервер пространства пользователя обращается к API до рендеринга. Авторизация осуществляется через JWT.

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

Так выглядит шаблон по-умолчанию:



Панель администратора выглядит следующим образом:



Верстка адаптивная, для пространства пользователя и панели администратора используется UIkit. Это отличный CSS фреймворк. который содержит большое количество уже готовых к использованию компонентов, легко поддается кастомизации и поддерживает «из коробки» Webpack.

Сфер применения CMS несколько, но основной задачей (как уже сказал выше) я вижу разработку легковесного решения для создания сайтов средней сложности, которые бы использовали возможности как современного Javascript, так и большого числа современных инструментов разработки и хранения данных.

План по дальнейшей разработке на относительно ближайшее будущее следующий:

  • Необхдимо на(до)писать документацию по разработке модулей, а также по готовым компонентам панели администратора
  • Продумать и написать тесты (сейчас их нет вообще :)
  • Прикрутить регистрацию/авторизацию/личный кабинет со стороны клиента + авторизацию через соц. сети (OAuth)
  • Разработать необходимые модули с допонительным функционалом (блог, каталог товаров, Интернет-магазин и т.д.)

Демо-версия с некоторыми функиональными ограничениями находится здесь: demo.zoiajs.org, также доступна панель администратора (логин: admin, пароль: password). Каждый ровный час база сбрасывается к настройкам по-умолчанию, нужно будет проходить повторную авторизацию.

Код CMS доступен на Github, так что при желании можно присоедниться к разработке, репортить баги и т.д. Я буду рад контрибьюторам ;-)

Комментарии (19)


  1. kmx
    31.10.2019 22:34

    и ссылки все битые в статье на сайт (демка и админка)


    1. kmx
      31.10.2019 22:58

      все же не хабра-эффект а битые ссылки
      на гитхабе корректные:
      Demo (is being reset to defaults every single hour!): demo.zoiajs.org, Admin panel: demo.zoiajs.org/admin (use admin/password to authorize).


      1. xtremespb Автор
        01.11.2019 03:09

        Спасибо, не проверил ссылки. Там была опечатка ;-)


  1. kolbaskinmax
    31.10.2019 22:44

    Наверное, хабра-эффект, админка не открывается.
    Пара комментариев по коду:
    1. Уберите в какую-нибудь абстракцию взаимодействие с респонсами, эти ваши JSON.stringify на каждый чих в АПИ выглядят не кашерно.
    2. Тоже самое касается работы с базой.
    3. В 2019 году продвигать проект без тестов, по-моему, мертвая затея…
    В любом случае, опыт бесценен, удачи в вашем начинании.


    1. xtremespb Автор
      03.11.2019 17:33

      1. Я хочу, чтобы API возвращало JSON в виде текста. Почему здесь плох JSON.stringify?

      return rep.code(200)
                      .send(JSON.stringify({
                          statusCode: 200,
                          config: req.zoiaConfig,
                      }));
      

      Вы имеете ввиду, что вместо «req.send(JSON.stringify(...» имеет смысл сделать какой-то красивый метод-обёртку?
      2. Я бы удовольствием сделал какую-то библиотеку для работы с различными БД через адаптеры. Хочется, чтобы была поддержка как SQL, так и не noSQL баз. Не подскажете, есть ли что-то такое? Возможно, я пропстуил.
      3. Это не проект без тестов, это проект, где пока всё тестируется руками. Тесты, собственно говоря, будут, как только до них дойдут руки.

      Ну и спасибо за пожелания.


      1. kolbaskinmax
        04.11.2019 00:12

        1. Я ничего не имею против конкретно JSON.stringify. Почитайте про основные принципы solid. Вот тут подробно расписано: medium.com/webbdev/solid-4ffc018077da Следование, хотя бы в общих чертах, этим принципам сэкономит вам кучу времени в будущем.
        2. см п.1. Если следовать принципу инверсии зависимостей (буква D в акрониме SOLID), обращение непосредственно к mongo должно быть через некоторую абстракцию.

        У вас сейчас в методах АПИ:

        this.mongo.db.collection('pages').findOne(.....)

        Если вы захотите поменять mongodb на что-то другое, вам придется переписывать все ваше приложение.

        Но если создать свой класс для работы с базой, и к монге обращаться только внутри этого класса, то для смены типа базы данных вам нужно будет переписать только этот класс. Вы даже сможете поддерживать оба типа СУБД — sql и nosql.

        3. Посмотрите в сторону TDD. В проектах с АПИ разработка через тестирование здорово экономит время и упрощает жизнь вашим последователям.


  1. radist2s
    01.11.2019 07:13

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


    1. xtremespb Автор
      03.11.2019 17:26

      Можно клонировать Pages и добавить туда любые кастомные поля, это достаточно просто делается.
      Gutenberg — прикольная штука, спасибо. Возьму на вооружение.


  1. northmule
    01.11.2019 08:56

    Приятная cms, мне понравилась!


  1. alexesDev
    01.11.2019 09:32

    Есть очень много headless cms, которые можно использовать с gastby/next.js или еще чем в качестве head.
    https://ghost.org/
    https://strapi.io/
    и тп по запросу headless cms


  1. index0h
    01.11.2019 10:09

    я не встречал ни одной реактивной CMS, полностью написанной на JS и использующей Mongo в качестве БД (напишите, пожалуйста, в комментариях, если такое есть, а я пропустил)

    Вы видимо и не искали вовсе. Первый же результат в гугле 11 Best Node.js-based CMS as of 2019


    Не понятна мотивация создания подобной cms.


    1. xtremespb Автор
      01.11.2019 18:00

      При чем тут CMS на Node? Zoia — прежде всего реактивная CMS, под Node работает только API, веб-сервер и вспомогательные утилиты для сервера


      1. index0h
        01.11.2019 20:11

        При чем тут CMS на Node?

        При том, что у вас CMS на ноде, таких много, в чем фишка именно вашей?


        под Node работает только API, веб-сервер и вспомогательные утилиты для сервера

        вы еще про сборку и раздачу фронта забыли))


        1. xtremespb Автор
          01.11.2019 21:55

          Вы, видимо, не до конца поняли архитектуру Zoia.
          Node здесь используется только для API, который взаимодействует с БД и является по сути поставщиком данных, и для веб-сервера, который как раз «раздает фронт». Львиная доля функционала связана с админкой, которая как бы SPA и к Node отношения не имеет.


  1. alexandrtovmach
    01.11.2019 20:59

    xtremespb Вы проделали много хорошей работы, но увы я соглашусь с тем что надобности в подобной CMS пожалуй нет. Мотивация использования именно JS не до конца ясна из статьи, поэтому сложно рекомендовать что-то конкретное, но вот парочка написанных на React/Gatsby:



    Или найдите идеальную CMSку для себя здесь: https://headlesscms.org/


    1. xtremespb Автор
      01.11.2019 21:53

      tinacms.org требует навыки программирования для того, чтобы развернуть CMS.
      Та же история с KeystoneJS.
      Netlify CMS — это по сути надстройка над статическим генератором сайтов.

      Но где же старая добрая CMS, на которой можно было бы быстро, просто и удобно развернуть, например, простой сайт-визитку — без колдунства и шаманства?


      1. alexandrtovmach
        01.11.2019 22:31

        Netlify CMS — не требует навыков программирования, и подходит под ваши требования вне зависимости от того чем является.


        Если опишите причины зачем нужна CMSка написанная на React и использующая MongoDB и вдобавок плюс/минус требования к ней, то можно подобрать что-нибудь всё на том же сайте.


        Вы не подумайте, я не хейтер, мне просто интересно понять чем концептуально отличается ваш продукт от уже существующих на рынке?


        1. xtremespb Автор
          03.11.2019 17:24

          Да, спасибо за Netfly. Я посмотрел вот этот tutorial, и всё равно не понял, как мне без сложных танцев с бубном import, collections и т.д. быстро и просто развернуть элементарную «визитку».
          Для меня задача стоиит следующим образом: сделать максимально гибкое решение, которое для конечного юзера будет не сложнее обычной PHPной CMSки, при этом будет использовать всё хорошее, что есть в зоопарке соверменного стека JS разработке. Чтобы развернуть простой сайт на Zoia, достаточно git clone && npm i && npm run configure && npm run build — всё, можно запускать готовый сайт, всё уже работает как надо. Допустим, надо сделать мобильное приложение для сайта — ОК, тоже не проблема, есть удобное API. То есть вот как-то так оно и задумывалось.


  1. savasanek
    01.11.2019 21:55

    Посмотри в сторону Strapi, может тоже понравится :)