# CMS

## Что это такое
CMS(Content Management System) - система управления контентом. Простыми словами — эта штука позволяет сохранять контент в виде страниц и получать его на фронтах.

## Для чего мы используем cms

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

Например:
* морда в приложении
* виджеты км
* рич-контент на км
* рич-контент в каталоге
* виджеты в корзине
* данные по вакансиям
* различную информацию по кэшбэку
* информацию по доставке и коронавирусу
* сториз
* и многое другое

При правильном использовании это очень мощная штука. Она позволяет динамически менять контент приложения без выпуска новой версии приложения. Вот только с большими возможностями приходит и большая ответственность, надо быть осторожным с CMS, так как местами есть возможность отстрелить ноги ВСЕЙ КОМАНДЕ.



## Страница

По большому счету контент из cms мы получаем страницами.
Упрощенно процесс выглядит так:
* мобильное приложение дергает резолвер "resolveCms" FAPI с определенными параметрами
* FAPI берет эти параметры, обогащает их дополнительными параметрами и идет в темплатор.
* темплатор возвращает FAPI список подходящих страниц, FAPI отдает их мобильному приложению
* мобильное приложение пытается распарсить ответ, и, если не было ошибок, показывает контент

### Типы страниц

Под разные задачи заводятся разные типы страниц. Например:
* морда - mp_morda_app
* рич-контент в каталоге - mp_catalog_rich_app
* корзина - mp_cart_app
* информация о доставке в режиме локдауна - mp_corona_delivery
* и т.д.

**Каждый тип страницы может иметь свои настройки**

Во вкладке "Свойства материала" редактора схемы имеем следующие возможные параметры:
* Заголовок — как будет называться тип страницы для контентщиков
* Корневой узел — задает корневой узел страницы, в зависимости от конфигурации этого узла будем иметь разный возможный контент для страницы
* Группа похожести — черт знает что это значит
* - Проверки после публикации — судя по всему можно настроить дополнительные проверки (автор не использовал этот функционал)

Во вкладке "Форматы экспорта" для страницы настраивается формат экспорта для различных платформ.
Формат экспорта — формат получения контента, настраивается под платформы типа:
* desktop
* phone
* tablet
Можно настроить получение данных в json или xml.

В формате экспорта можно задать дополнительные настройки материала:
* клиент - tbd
* URL - tbd
* Поля-идентификаторы - tbd
* Ответственные — список людей, к которым пойдут в первую очередь, если с этим документом этого типа что-то не так
* Шаблоны ключей — набор параметров, которые необходимо прокинуть до темплатора, чтобы получить документ. Можно задать несколько шаблонов и получать страницы по разным наборам ключей. Если указать шаблон уникальным, то не будет возможности создавать 2 страницы с одинаковыми параметрами под этот шаблон.

### Связи страниц

Связи страниц позволяют разделять страницы для разных пользователей. Например, есть возможность отдавать разные страницы пользователям из разных стран. В мобильных приложениях чаще применяется связь с rearr флагом, что позволяет отдавать пользователям в разных экспериментах разные страницы.
Это можно посмотреть на примере страниц типа "Беру / Морда приложения". На текущий момент имеется множество опубликованных "морд" приложения привязанных к разным rearr флагам.

## Виджеты

Если типы материалов являются описанием страниц, которые мы можем получить из cms, то типы узлов — это описание "блоков", из которых может состоять страница. Корневой узел страницы определяет корневой объект, который отдает страница.


Сами узлы подобны ```*.dto``` классам в android приложении. При желании можно извратиться и отобразить в этих узлах что угодно (или почти что угодно). Дальше рассмотрим узлы на примере виджетов.


Виджеты наследуются от типа узла типа ```WIDGET_REACT```. При редактировании виджета (как и любого узла) в редакторе доступны следующие вкладки:
* Свойства типа
* Свойства полей
* Свойства по путям (подробнее ([тут](https://wiki.yandex-team.ru/market/cms/docs/development/Branchovye-svojjstva-u-nod-svojjstva-po-puti/)))
* Шаблоны экспорта
* Родительские типы

### Свойства типа

Здесь доступны 3 блока настроек:
* export_include__full_ - tbd
* label - как будет называться виджет в типах узлов
* widget_title - tbd

### Свойства полей

Настраиваемые поля виджета. При добавлении нового поля можно задать множество его параметров, например:
* allowedTypes - здесь можно перечислить типы узлов, которые можно задать в это поле (сюда можно вписывать типы разрешенных узлов, например, если вы сделали особый узел с конфигурацией, его можно подключить к вашему виджету, и он будет отображаться в редакторе прямо внутри вашего виджета)
* label - название поля отображающееся в редакторе CMS
* default_value - значение по умолчанию
* value_type - если поле имеет какой-то примитивный тип (строка, число и т.д.) можно указать его тут
* help - подсказка для контентщиков

### Свойства по путям

Автору не приходилось это использовать, но если что, подробнее почитать что это и для чего можно [тут](https://wiki.yandex-team.ru/market/cms/docs/development/Branchovye-svojjstva-u-nod-svojjstva-po-puti/)

### Шаблоны экспорта

Задает формат вывода виджета. То есть то, как он будет выглядеть в финальном json.  По сути делаете набросок json (при этом можно не весь json, а только часть его, если хотите этот узел прокинуть внутрь других узлов), только можете вместо значений указывать поля виджета с суффиксом и постфиксом в виде 2 нижних подчеркиваний. Пример:
```json
{
    "entity": "widget",
    "name": "MultiScrollBox",
    "id": __WIDGET_ID__,
    "loadMode": __LOAD_MODE__,
    "placeholder": __PLACEHOLDER__,
    "hideCriteria": __HIDE_CRITERIA__,
    "groups": [__GROUPS__],
    "wrapperProps": __WRAPPER_PROPS__,
    "props": {
    __COMMON_WIDGET_PARAMS__,
    "anchor": __ANCHOR__,
    "size": __SNIPPET_SIZE__,
    "ratio": __RATIO_ELEMENT_TO_CAROUSEL__,
    "withGutters": __WITH_GUTTERS__,
    "gutter": __GUTTER_SIZE__,
    "showControls": __SHOW_CONTROLS__,
    "controlsSize": __CONTROLS_SIZE__,
    "align": __VERTICAL_ALIGN__,
    "horizontalAlign": __HORIZONTAL_ALIGN__,
    "snippets": __SNIPPET_PROPS__,
    "thumbs": __SB_THUMBS__,
    "controlsPlacement": __CONTROLS_PLACEMENT__,
    "minCountToShow": __MIN_COUNT_TO_SHOW__,
    "deduplicate": __DEDUPLICATE__,
    "priceLinkToOffers": __PRICE_LINK_TO_OFFERS__,
    "additionalQueryParams": __ADDITIONAL_QUERY_PARAMS__
    }
}
```
В примере выше видно поле ```__COMMON_WIDGET_PARAMS__```, его шаблон экспорта выглядит следующим образом:
```json
    "title": __TITLE__,
    "authTitle": __AUTH_TITLE__,
    "subtitle": {
      "type": __SUBTITLE_TYPE__,
      "text": __SUBTITLE__
    },
    "titleParams": {
      "size": __TITLE_SIZE__,
      "type": __TITLE_TYPE__,
      "align": __TITLE_HORIZONTAL_ALIGN__,
      "tag": __TITLE_TAG__
    },
    "link": __LINK_WITH_CAPTION__,
    "paddingTop": __PADDING_TOP__,
    "paddingBottom": __PADDING_BOTTOM__,
    "paddingLeft": __PADDING_LEFT__,
    "paddingRight": __PADDING_RIGHT__,
    "backgroundColor": __CSS_BACKGROUND_COLOR__,
    "backgroundImage": __BACKGROUND_PICTURE__,
    "backgroundPosition": __BACKGROUND_POSITION__,
    "backgroundSize": __BACKGROUND_SIZE__,
    "theme": __THEME__,
    "titleStyle": __TITLE_STYLE__,
    "metrika": __METRIKA__,
    "compensateSideMargin": __COMPENSATE_MARGIN__
```
Таким образом, во многие виджеты (которые используют COMMON_WIDGET_PARAMS) добавлены множество полей настроек виджета.

### Родительские типы

Позволяют посмотреть, от каких типов наследуется виджет. Хз зачем еще этот пункт нужен.

### Полное описание редактора CMS
https://wiki.yandex-team.ru/market/cms/editor/Редактор-схемы-CMS/


## Советы
* Старайтесь не создавать "статичных" виджетов без источника данных. Желательно, чтобы виджет можно было конфигурировать и поддержать это как на стороне CMS, так и на стороне приложений.
* При редактировании страниц/виджетов/узлов проверяйте, что ваши правки не ломают старые версии приложений. У нас всегда большой хвост старых версий, и любая ошибка может привести к негативным отзывам.
* К сожалению уже долгое время не работает репликация данных CMS с прода в тестинг, поэтому придется многое править на проде, а значит БУДЬТЕ МАКСИМАЛЬНО ОСТОРОЖНЫ! Закрывайте свои тестовые страницы rearr флагами, чтобы никто кроме вас и тестировщиков не смог получить к ним доступ. Ну и выставляйте на этих страницах максимально нейтральный контент.
* Если хотите посмотреть как реализован тот или иной узел на странице, открываете страницу в редакторе CMS, находите нужный узел, выделяете его, справа сверху будут 4 кнопки, среди них находите ```<>``` ()
