Intro

Привет! Сегодня я хочу представить вам плод моего многомесячного труда по ночам и выходным, призванный улучшить опыт управление контентом и привнести в мир разработки Flutter-приложений дополнительные возможности.

Далее речь пойдет о Nanc (читается как Нэнс, но я внутренним голосом постоянно произношу "Нанк" ????) - Not A Normal CMS. Почему она "не нормальная" и что с её помощью можно делать вы узнаете, осилив эту статью. Кое с чем вы даже сможете поиграть - эта статья содержит ссылки на демо с клиентским и CMS-приложением, позволяющие получить представление "что к чему".

Для того чтобы показать общественности возможности Nanc были сделаны два приложения: клиентское, имитирующее любое Flutter-приложение и дающее представление о том, что может дать таким приложениям Nanc.

И приложение Nanc, представляющее из себя предварительно сконфигурированную CMS с дополнительно внедренным слоем логики синхронизации клиентского приложения с CMS.

В конце большинства логических блоков текста вы обнаружите youtube-видео с примером использования / демонстрацией того или иного аспекта Nanc.

Table of contents

  1. Intro

  2. About CMS

    1. Types of models

      1. Collection

      2. Solo

    2. Editor

      1. Общее описание

      2. Code-first

      3. Interface-first

      4. Hybrid mode

    3. Fields

      1. Bool

      2. Color

      3. Date

      4. Dynamic

      5. Enum

      6. Header

      7. Icon

      8. Id

      9. MultiSelector

      10. Number

      11. Selector

      12. String

      13. Structure

      14. Screen

  3. Dynamic Flutter apps

    1. Interactive documentation

    2. Extensibility

    3. Simplicity

    4. The Power

    5. Convenience

    6. Performance

  4. Nanc demo apps

    1. Общее описание

    2. Client

    3. Admin

    4. Connection manager

  5. What's next / Afterwords

About CMS

Итак. Nanc - это backend-agnostic CMS, которая не тянет за собой свой собственный бэкенд. Как это работает? Nanc предлагает реализовать интерфейсы сетевых сервисов, в которых прямо сейчас 6 методов, но к моменту релиза будет около 10. Много это или мало? Например, для реализации API для демо-приложения понадобилось написать 170 строк кода. Эти методы отвечают за всю работу Nanc с вашим существующим бэкендом. Реализация должна быть написана на языке Dart (язык разработки и для Flutter). В будущем Nanc будет поставляться с уже готовыми вариантами реализации этих интерфейсов под определенные варианты бэкендов - Firebase, Supabase, локальный / сетевой SQLite и Generic-реализация REST и GraphQL (может что-то еще?) и вам не придется думать об этой реализации вообще или придется, но совсем чуть-чуть.

Types of models

Модель в Nanc - это структурное описание какой-либо сущности, которой вы хотите управлять с помощью Nanc. Модель содержит название сущности, различные визуальные параметры и описание полей.

Collection

Коллекция - это некая сущность, у которой может существовать множество вариаций. Список пользователей, книг, отзывов - хорошие примеры моделей типа "Коллекция" в Nanc.

Если вы знакомы с реляционными базами данных, то примером Коллекции в Nanc будет практически любая таблица в вашей базе.

Solo

Соло (модель) - это сущность, существующая в единственном экземпляре. Например - Список Feature Toggles, или конфигурация чего-либо или..."Главный экран мобильного приложения". В целом Solo-модели призваны повысить удобство работы, являясь всего-лишь проекцией вашей базы данных. И Solo-моделью легко может быть и какая-нибудь таблица вашей БД, с одной-единственной записью. Но на текущий момент реализация этого класса моделей обязывает, чтобы запись этой модели (строка в БД) имела id, аналогичный id самой модели.

final Model landingPage = Model(
  name: 'Landing page',
  /// ? id in format [toSnakeCase(name)] will be set automatically, if omitted
  // id: 'landing_page',
  isCollection: false,
  icon: IconPackNames.flu_document_page_break_regular,
  fields: [
  ...

Editor

Общее описание

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

Code-first config

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

  • id

  • title

  • image

  • description

А реализация в виде code-first config будет иметь следующий вид:

import 'package:fields/fields.dart';  
import 'package:icons/icons.dart';  
import 'package:model/model.dart';  
  
final Model feature = Model(  
  name: 'Feature',  
  icon: IconPackNames.flu_ribbon_star_filled,  
  fields: [
    [
      IdField(width: 200),  
      StringField(name: 'Title', maxLines: 1, isRequired: true, width: 400),  
    ],  
    [  
      IconField(name: 'Image', isRequired: true),  
    ],  
    [  
      StringField(name: 'Description', isRequired: true, showInList: true),  
    ],  
  ],  
);  
  

Описав такую модель и внедрив ее в Nanc CMS вам становится доступным весь CRUD этой модели.

Interface-first config

Точно такую же модель Feature (назовем ее Feature Variant) мы могли бы создать и через интерфейс Nanc. При этом (учитывая, что все подготовительные работы для использования Nanc сделаны) - при создании модели в Nanc вы сразу же создадите и таблицу в базе данных, и точно также весь CRUD вам будет сразу доступен.

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

Hybrid config

Этот вариант становится вам доступен, когда вы, имея Code-first config, решили изменить его посредством интерфейса Nanc. В этом случае все дальнейшие изменения этой модели будут возможны только через интерфейс, а изменения, внесенные и оригинальную code-модель будут проигнорированы. Единственный способ вернуться к Code-first - это "сбросить" модель - в этом случае все изменения в структуре модели, внесенные через интерфейс, будут помножены на ноль (жаль, что только они) и снова начнет использоваться актуальный Code-first config. Никакие данные при таком сбросе не затрагиваются, это касается только структуры модели.

Fields

Теперь рассмотрим, какие типы полей Nanc поддерживает на данный момент.

Boolean

BoolField позволяет управлять типом данных bool и настраивать значение по умолчанию.

Color

ColorField предоставляет вам удобный color-picker, позволяющий выбирать цвет сразу же в Nanc. А также дает возможность вносить изменения вручную, посредством редактирования AHEX-кода. AHEX - это классический HEX-Color (например - #10A0CF), но с дополнительным значением прозрачности, указываемым вначале. В данном случае этот цвет будет аналогичен цвету #FF10A0CF (FF - 100% непрозрачность - цвет полностью непрозрачен). А так бы выглядел этот же цвет с 50% непрозрачности: #7F10A0CF.

Date

DateField отвечает за управление датой и временем (оба значения сразу, отдельные для даты и времени будут реализованы позднее). DateField содержит два boolean-параметра, которые позволяют модифицировать поведение данного поля, сделав из него timestamp времени создания сущности и timestamp времени изменения.

Dynamic

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

Enum

EnumField - поле для выбора какого-либо значения из нескольких значений. Правило, которого стоит придерживаться, выбирая EnumField - если у вас есть конечный список значений для выбора, не хранящийся в отдельной таблице базы данных - выбирайте Enum. В противном случае - SelectorField, подробнее о котором будет ниже. TODO: В настоящий момент это поле может быть сконфигурировано только через CodeConfig, конфигурация через интерфейс не проработана.

Header

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

Icon

IconField предоставляет вам возможность выбирать иконку (класс IconData) из предопределенного набора иконок. На данный момент их около 25.000 и в этот набор входят следующие иконки:

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

Можно задаться вопросом "Иконки есть, цвета есть, а шрифты?". Если вы так и сделали, то ответ вы сможете найти в документации к виджету Text. Краткий ответ - вам доступны все шрифты из Google Fonts.

Id

IdField - такое простое, но такое важное поле. В каждой модели, управляемой Nanc, должно присутствовать хотя бы одно поле типа Id. На данный момент поддерживается только строковый тип ID (он может быть любой уникальной, в рамках одной сущности, строкой). Планируется добавить поддержку и числового типа, что, впрочем, возможно реализовать и сейчас, просто типизируя данные поля числового типа в API-реализации.

Multi-selector

MultiSelectorField - довольно непростое поле, отвечающее за реализацию реляционного отношения "многие ко многим" или "многие к одному". Есть три режима использования данного поля. Пройдемся более детально по каждому из них. TODO: В настоящий момент это поле может быть сконфигурировано только через CodeConfig, конфигурация через интерфейс не проработана.

Array of ids

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

/// user table  
{  
  id: 'UUID',  
  name: 'String',  
  books: [  
    'UUID',
    'UUID'  
    // ...  
  ]  
}  

Выше представлена примерная структура таблицы, выраженная с помощью JSON5-синтаксиса.

Минусом данного режима является ограниченная целостность данных. Если вы не реализуете автоматическое удаление устаревших (удаленных) идентификаторов книг из поля books Читателя - вы получите ошибки.

Third table

Классический режим обеспечения отношений из мира SQL. При использовании данного режима вы храните связи сущностей в отдельной таблице, и обеспечиваете 100% целостность данных. Следующая структура может являться примером данного режима:

[  
  /// user table  
  {  
  id: 'UUID',  
    name: 'String'  
  },  
      
  /// book table  
  {  
    id: 'UUID',  
    title: 'String'  
  },  
      
  /// user_books_relations table  
  {  
    user_id: 'UUID',
    book_id: 'UUID'  
  }  
]  

На 7й секунде видно небольшое подергивание и если присмотреться, то можно заметить, что изменился url страницы - это я так попытался скрыть баг: в режиме third table данные сохраняются в родительской странице только если она уже была сохранена ????????‍♂️

Array of objects

В целом аналогичен Array of ids, только хранятся в родительской записи не идентификаторы, а целиком весь объект (в виде плоской структуры, без возможных связанных сущностей вложенной записи). Обладает тем же минусом, что и Array of ids, но несет и дополнительный - увеличенное использование хранилища. Однако область применения данного режима (по крайней мере на данный момент) - есть, и она очень важна. Но об этом мы поговорим несколько позднее.

В видео я немного забегаю вперед, показывая ScreenField, к этому мы еще вернемся

В целом есть идея, сделать "не каноничные" режимы виртуальными - чтобы они так или иначе работали через Third table, а необходимые данные загружались при редактировании страницы (если это нужно).

Number

NumberField хранит числа - вот так просто и все.

Selector

SelectorField схож с MultiSelectorField (как вы могли догадаться по их названиям), но немного проще - связь тут "один к одному" или "один ко многим", а режимов два. TODO: В настоящий момент это поле может быть сконфигурировано только через CodeConfig, конфигурация через интерфейс не проработана.

Id

Обычный для SQL вид обеспечения связи, когда в поле родительской записи хранится идентификатор связанной. Возьмем за основу примера Читателя. Кто это? В первую очередь это человек, а что есть у человека? Правильно! Город рождения (который наша Библиотека, почему-то, тоже захотела знать).

/// user table  
{  
  id: 'UUID',  
  name: 'String',  
  birth_place_id: 'UUID'  
}  

Object

Очень схож с Array of objects из MultiSelectorField, но хранить мы будем одно единственное связанное значение в поле родительской записи. Минусы те же, плюсы, так же, будут описаны совсем чуть-чуть ниже.

String

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

Structure

StructureField позволяет вам хранить в записях модели массив типизированных структур. Вы указываете тип хранимых данных и легко и просто можете ими управлять. Доступные типы для полей структуры - абсолютно все. Поэтому вы легко можете создать "Dynamic Structure Field Repeat". TODO: В рамках демо добавлять в StructureField можно только "плоские" поля.

Screen

ScreenField - поле, позволяющее вам написать целое приложение на Flutter, прямо в Nanc! Со ScreenField вы можете описать интерфейс отдельного...screen (экрана), обновлять его как захотите, и делать это в любой момент времени за несколько минут - без утомительных и нервозных ожиданий ревью от Apple и Google.

Давайте немного подробнее разберем этот тип поля (а на самом деле - целое отдельное функциональное ответвление Nanc).

Dynamic Flutter apps

С помощью ScreenField вы действительно можете создать интерфейс практически любой сложности прямо в браузере (и вашей IDE), а затем, не делая публикаций в сторах - обновить соответствующий экран в вашем приложении. Если вам необходимо проверять гипотизы быстро - это отличная возможность. Эта функциональность отлично подойдет для относительно простых (с точки зрения логики) страниц вашего приложения, которые, однако, должны меняться довольно часто. В будущем этот функционал будет расширен до состояния, когда вы сможете создать действительно все, что захотите, без каких-либо ограничений.

Теперь пройдемся во всем аспектам создания динамических экранов с помощью Nanc.

Interactive documentation

Во Flutter много виджетов. Очень много. Что такое виджет? Это кирпичик функциональности, из которых вы собираете ваше приложение. Он может быть как только визуальным, так и логическим - с определенным поведением внутри. Nanc предоставляет обширный перечень реализованных виджетов, которые вы можете использовать для создания UI. Но чем больше возможностей - тем сложнее о них узнать... Поэтому редактор экрана в Nanc дает вам доступ к интерактивной документации, где вы можете узнать, какие виджеты реализованы на данный момент, какие у них есть параметры и настраиваемые свойства, а также, прямо в документации, посмотреть, как они влияют на внешний вид создаваемого интерфейса.

Simplicity

Nanc позволяет создавать интерфейс в реальном времени, но главное - он позволяет делать это очень просто и быстро (на интерфейс демо-приложения ушло немногим больше 2х часов). Но назревает вопрос - а как создавать сам UI? В Nanc нет какого-то экзотического синтаксиса для описания UI, ровно как и "слишком" простых решений, вроде длинного, для таких задач, JSON, которые заставят вас возненавидеть процесс создания интерфейсов в Nanc.

Результатом поиска оптимального решения является простой и понятный синтаксис XML. Все стандартные виджеты Flutter имеют ровно те же названия, но в виде XML. Например, виджет SizedBox в Nanc будет <sizedBox>...</sizedBox>, и это правило применяется ко всем виджетам без исключения. Если у виджета есть какое-то сложное свойство, то оно будет иметь такое-же (или более простое) название в виде XML, с префиксом prop. Например - у виджета Container есть комплексное свойство boxDecoration, у которого есть свои внутренние свойства. Так вот, это свойство в Nanc будет иметь следующий вид: <prop:decoration>...</prop:decoration>. Это правило применяется ко всем сложным свойствам. И последний аспект - аргументы, являющиеся относительно простыми - это параметры XML-тегов. Посмотрим на примере того же SizedBox:

  
<sizedBox width="50" height="50">  
    ...  
</sizedBox>  

При этом, для некоторых виджетов реализованы и дополнительные аргументы, упрощающие написание кода, и у SizedBox это аргумент size, задающий одновременно width и height.

Все, что написано тут - есть в интерактивной документации, поэтому, если вы что-то забыли или хотите узнать - обращайтесь к ней и найдете там ответы на все вопросы.

Extensibility

Реализовать поддержку нового виджета - дело от 10 минут до нескольких часов. На данный момент имплементированы практически все основные виджеты, из которых можно создать сложный интерфейс с логикой. Со временем в Nanc будут реализованы все доступные во Flutter виджеты и вы сможете сделать действительно все. Но это не все. Вы можете легко и просто реализовать свои собственные виджеты и использовать их в Nanc с помощью одной-двух строчек XML-кода. Например - в стандартной библиотеке Flutter нет виджета, позволяющего отобразить легко отобразить Carousel Slider с картинками. Вам придется писать реализацию самостоятельно или использовать какое-либо open source решение, например такое. И, реализовав то, что вам нужно - вы можете очень легко интегрировать ваш виджет в Nanc и использовать его.

The Power

Nanc предоставляет не просто возможности по преобразованию XML-кода в интерфейс на Flutter. Nanc дает возможности шаблонизации и написания логики. Условная отрисовка элементов, отрисовка в цикле, обработка тапов - это уже есть в текущей 0.0.1 версии Nanc.

Пока все, что связано с логикой, довольно просто - реализована поддержка взаимодействия посредством нажатий на элементы и обработка соответствующих событий в вашем .dart коде, написанном заранее, но со временем эта часть Nanc будет серьезно расширяться, позволяя вам писать логику на Dart прямо в браузере и работать она будет и в вашем приложении.

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

Convenience

В Nanc есть встроенный XML-редактор, однако, он не очень удобен. В нем (пока) нет поиска, он не очень быстрый при большом объеме кода и в нем нет автодополнения. Как с этим жить? Например - позволить пользователю использовать его любимую IDE и в реальном времени наблюдать изменения в Nanc. Сейчас покажу как.

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

А это Web (с которым вам и предстоит играть):

В будущем будет добавлена поддержка автодополнений, возможно в отдаленном...я пытался в XML Schema, потратил несколько дней, но пока не смог ????????‍♂️

Performance

Отдельно хотелось бы упомянуть про производительность (отрисовки интерфейса из XML на мобильных девайсах). Если кратко - она аналогична производительности самого Flutter, без какого-либо оверхеда. На текущий момент "экран" представляет из себя лениво отрисовывающийся список виджетов (SliverList), создающихся асинхронно. Немного позднее данная реализация будет доработана, чтобы виджеты начали отрисовываться также асинхронно, но по очереди, таким образом время, требуемое на показ контента будет равно времени, требуемому для отрисовки самого первого виджета, описанного в XML.

Nanc demo apps

Общее описание

Для демонстрации возможностей был создан публичный набор демо-приложений, которые показывают, чего можно достичь с помощью Nanc прямо сейчас. Это клиентское приложение на Android и Web (последнее временно играет и роль приложения для iOS). А также CMS-приложение Nanc. Подробнее о них ниже.

Links

Client

Client - это клиентское демо-приложение, использующее одну единственную библиотеку из nanc-экосистемы. Эта библиотека позволяет преобразовать XML в интерфейс приложения на Flutter. В этом приложении всего один экран, созданный полностью в Nanc и его можно обновлять как угодно и в любой момент времени без сторов. Справа снизу есть кнопка с иконкой подключения - она отвечает за подключение к демо-CMS. Подробнее о том, что это за "подключение" будет ниже.

Admin

Admin - это Nanc-CMS демо-приложение, с дополнительно внедренным слоем логики, обеспечивающим возможность синхронизации с клиентами (подробнее о подключении ниже). В демо-приложении Nanc-CMS в качестве "бэкенда" выступает сам браузер пользователя и его localStorage. Все, что вы добавите или измените - будет храниться только в вашем браузере. В Nanc-CMS вы можете изменять / создавать / удалять данные, относящиеся к существующим моделям (вы их увидите), а также - вы можете создавать посредством интерфейса свои собственные модели и делать с ними все тоже самое.

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

Connection manager / "Подключение"

Этот раздел относится исключительно к логике "демо" в клиентском и CMS-приложениях. И реализован он был, чтобы просимулировать опыт взаимодействия с Nanc и процесс обновления клиента. Но обо всем по порядку.

В реальном production-проекте вы могли бы использовать Nanc следующим образом - развернуть где-нибудь статическое приложение Nanc CMS, с реализованными API-сервисами. Оно бы общалось с вашим бэкендом, а вы использовали Nanc на свой вкус и цвет. Ваше приложение содержит одну библиотеку из nanc-экосистемы, позволяющую отрисовать интерфейс. Вы сделали обновление - приложение загрузило новый код из вашего бэкенда, обновилось - все счастливы и довольны.

Для показа этой модели в действии реализовано все тоже самое, но в упрощенном виде:

Nanc CMS существует как статика, лежащая на github pages и вы можете ей пользоваться так же, как "в реальной жизни", но в качестве бэкенда выступает ваш браузер. То есть интерфейсы API были реализованы таким образом, что "ходят в сеть" они - в браузерный localStorage. С этой частью завершили, но еще есть мобильное приложение, которое должно как-то показать вам процесс "обновления". Что же, тут то и нужно "подключение". Если кратко - вы можете установить прямое соединение между любым клиентским демо-приложением Nanc и любым CMS демо-приложением Nanc. Для этого вам нужно в CMS нажать кнопку справа снизу с иконкой QR-кода. В появившемся модальном окне вы увидите QR-код. Дальше у вас есть два стула - вы можете отсканировать этот код с помощью мобильного (или браузерного) клиентского приложения, нажав в нем похожую кнопку справа снизу, тогда подключение установится автоматически. Либо вы можете нажать по QR-коду, и необходимые, для соединения, данные будут скопированы в буфер обмена. Затем эти данные вы должны будете вставить в поле для ввода в мобильном приложении, и подключиться нажатием кнопки. Когда соединение будет установлено - вы поймете сами. После этого вы сможете делать все, что хотите, с существующей страницей Landing Page, и видеть изменения в реальном времени (после сохранения) - в мобильном приложении.

Но вы не ограничены только Landing Page. Вы можете прямо в браузере создавать любые новые модели, наполнять их контентом, и если в ваших моделях будет поле для описания интерфейса (тип Screen) - то при сохранении таких сущностей, вы также увидите результат в приложении - экран из новой модели заменит существующий экран приложения. Единственный момент - так как клиентское приложение не знает, какого типа то или иное поле вашей свеже-созданной записи, то в нем заранее прописаны возможные идентификаторы, которые, ожидается, и будут ScreenField. Поэтому, если вы захотите создать экран полностью с нуля и отобразить его в приложении, то используйте в качестве значения поля IdField что-то из следующего списка:

  • screen

  • ui

  • page

  • interface

  • markup

  • view

Если вы что-то сломаете - просто сбросьте данные сайта admin.nanc.io (Chrome: F12 -> Application -> Application -> Storage -> Clear Site Data), ну и при повторном открытии клиентского приложения оно всегда будет загружать актуальный код экрана, созданный для этого демо. (Код из вашего браузера будет загружен, только если вы подключитесь)

И, напоследок, небольшой пример с созданием новой страницы новой модели, содержащей ScreenField, и отрисовкой его в приложении:

What's next?

Публичное демо готово. Вводная статья написана. Дальнейшие планы касательно Nanc - завершить функциональную целостность интерфейсного подхода к созданию моделей, сделав возможным конфигурирование всех полей - Enum, Selector и MultiSelector. Пофиксить известные баги, вроде изменения положения элементов в StructureField. Затем "блаблабла", а потом "то то то". Бэклога хватит на ближайшие пол года, как минимум, но дальнейшая модель расширения функционала будет строиться на потребностях клиентов, поэтому если у вас есть идеи / критика / нашли баг (а их тут навалом) / что-то еще - заполните форму, ссылка на которую доступна в клиентском демо-приложении.

Если вас заинтересовали возможности Nanc, и вы заинтересованы в сотрудничестве - тоже заполните форму и мы обязательно пообщаемся.

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


  1. Dmitry2019
    05.02.2023 20:29
    -2

    Доброго времени суток. У нас есть мощный движок CMS, с гибким API. Было бы интересно пообщаться и посмотреть, как можно синтегрироваться. Инфу про наш продукт можно посмотреть на meld-ms.com

    Напишите в личку, если интересно.


  1. hardtop
    06.02.2023 11:14

    Работа, конечно, проделана колоссальная! Не совсем понял, как именно правильно это надо использовать. Это что-то визуального конструктора, который генерит xml, а потом на его основе flutter-код?


    1. alphamikle Автор
      06.02.2023 12:58
      +1

      Спасибо!

      Это стоит рассматривать как:

      1. CMS

      2. Которая может быть использована с вашей текущей инфрой

      3. И которая позволяет (дополнительно к основному CMS-функционалу) создавать UI с (пока небольшой) логикой, используя для этого XML с наименованием тегов, аналогичным наименованию виджетов во Flutter

      Flutter-код из XML не генерится в прямом смысле слова. XML парсится в реальном времени, весь "экран", назовем его так, асинхронно преобразуется в виджеты, и затем используются только они.

      Чтобы начать использовать достаточно всего одной потребности - "хочу править контент", затем, если "хочу иметь возможность создавать и обновлять экраны Flutter-апок динамически" - то в ход идет UI Builder (назовем его так).


  1. evgajukov
    08.02.2023 08:56

    Очень интересный проект. А можно как-то полученные приложения встраивать в уже существующее flutter приложение в качество miniapp?