Предисловие

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

Слова благодарности

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

Приятный бонус

Хочу сразу оговориться, что это не реклама и не пиар, а искреннее желание помочь кому-то из читателей получить приятный сюрприз. Мой друг (вы могли видеть его в дневых топах Хабра) уже два года занимается сбором и централизацией знаний на некоммерческой основе. Он радуется небольшим событиям и когда к нему приходят за советом или с просьбой помочь что-то настроить или в чем-то разобраться (он своего рода адепт обучения).

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

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

Участников сейчас не много, поэтому шансы на победу существенные.

О модальных формах в Obsidian

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

Что такое модальные формы и есть ли альтернативы?

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

По факту, модальные формы сильно упрощают процесс управления хранилищем по ряду причин:

  • пользователь может контролировать порядок вызова и заполнения заметок;

  • пользователь может определять какие формы должны быть вызваны, как следствие, какие поля могут быть заполнены;

  • пользователь может масштабировать свое хранилище с нужной архитектурой и разветвлениями;

  • пользователь может интегрировать модальные формы в работу других плагинов (например TemplaterQuickAddDataView);

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

Специфика Modal Forms и возможные альтернативы

Что касается альтернатив - они есть, только важно понимать, что мы можем считать альтернативой, но обо всем по порядку.

Я готов выделить 2 категории возможных альтернатив:

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

  2. Модальные формы с возможностью назначения пользователем полей и порядка ввода/обработки данных.

Вот допустим, мы хотим создать задачу и используя плагин Tasks вызываем модальное окно для заполнения заранее определенных полей и как следствие, повлиять на содержимое своего хранилища. Считаем ли за альтернативу? Я бы так не сказал, потому что поля заранее определенны не пользователем, а разработчиком, как следствие мы можем интегрировать эту логику в свой пайплайн, но не выстроить пайплайн самостоятельно с использованием персонализированных модальных форм. Этот вариант я отношу к первой категории.

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

Пример модальной формы плагина `Tasks`
Пример модальной формы плагина Tasks

Или, например, используя Meta Bind мы создаем поле ввода, которое может динамически реагировать на изменения. Мы даже можем благодаря input полю suggester реализовать внесение пользовательских данных (которые можем тоже, к слову, динамически формировать) и оно будет выводиться в отдельном окне, не привязанном к текущей вкладке и рабочему пространству, т.е. формально это модальная форма.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 2.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 3.png

По ряду признаков, которые я сформулировал такие модальные формы относятся ко второй категории, но можем ли мы считать такой способ полноценной модальной формой? Опять же, я бы не стал и вот почему:

  1. Такая модальная форма работает только если эта сущность определена в конкретной заметке (речь не о шаблоне даже);

  2. Такая модальная форма сложно интегрируется со сторонними плагинами и как следствие, сложнее интегрируется в какой-то последовательный пайплайн;

  3. Такая модальная форма не может самостоятельно в полной мере способствовать управлению хранилищем, т.е. внеся какие-то данные в такую форму вы непосредственно можете изменить содержимое заметки и ее frontmatter, но не сможете создать новую заметку или изменить/удалить существующую.

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

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

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 4.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 5.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 6.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 7.png

Стоит оговориться, что благодаря возможностям, которые мы получаем используя Templater - мы можем реализовать практически безграничное количество пользовательских сценариев. Например, можно предложить выбрать какие-то поля frontmatter или теги из какого-то пулла заметок или выбрать конкретные файлы/директории, а потом обработать это нужным пользователю образом.

Но несмотря на это Templater не является самым оптимальным решением по ряду причин:

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

  2. Отсутствие удобного GUI при настройке форм.

Стоит оговориться, что я не рассматриваю Templater как оптимальное решение в контексте "автономного инструмента" для работы с модальными формами, но он является неотъемлемой частью для взаимодействия с пользовательским хранилищем. Что я имею ввиду?

В своей предыдущей статье я пытался показать насколько всеобъемлющи возможности этого плагина для взаимодействия с вашими хранилищем в целом и его заметками в частности. Пожалуй лучше него с такими задачами справится только API Obsidian. Т.е. надо использовать доступные инструменты на максимум, в случае с модальными формами, на мой взгляд, максимум Templater - это взаимодействие с хранилищем и обработка бизнес-логики, а управление формами оставим профессионалу (Modal Forms).

Идеальное решение для управления модальными формами

Таким образом, можно прийти к выводу, что идеальное решение для управления модальными формами должно соответствовать ряду критериев:

  1. Возможность управления пользователем полями, предлагаемыми к вводу;

  2. Полный контроль передаваемых данных;

  3. Возможность создания пользовательских сценариев заполнения таких форм с поддержкой разветвления, в зависимости от вводимых данных;

  4. Интеграция со сторонними плагинами для последующей передачи полученных данных и их обработки;

  5. Удобный GUI, позволяющий быстро ориентироваться в созданных формах.

И всем этим критериям соответствует плагин Modal Forms возможности которого мы сейчас разберем.

Мой опыт использования модальных форм и почему я пришел к Modal Forms:

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

Я искал какие есть способы для ввода/вывода пользовательских данных и по-началу наткнулся на tp.system.prompt и tp.system.suggester, но чтобы реализовать приятный интерфейс при вызове шаблона, нужно было неприятно заморочиться над логикой самого шаблона. К тому же, как бы я не старался, повлиять в тот момент на сам интерфейс я не мог совершенно никаким образом (пропускать поля, ставить переключатели и прочее).

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

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

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

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

Начало работы с модальными формами

Установка плагина

Для начала работы нам потребуется установить плагин в наше хранилище: Настройки > Сторонние плагины > Плагины сообщества > ищем Modal Forms > Install/Установить

В целом, порядок классический, но если мою статью будут читать начинающие пользователи Obsidian, то это может быть полезно

Знакомство с интерфейсом

У большинстве плагинов есть настройки, доступ к которым можно получить перейдя в настройки хранилища и перейдя в соответствующий раздел интересующего плагина, но в случае Modal Forms все не так и мы можем выбрать только где будет открыто меню редактирования форм и будет ли создан алиас для быстрого доступа к методам плагина:

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 8.png

Основные настройки содержатся непосредственно в меню редактирования форм. Для получения доступа можно воспользоваться как палитрой команд Cmd/Ctrl + P > Modal Forms: Manage forms так и ярлыком на боковой панели, если вы предварительно создали соответствующую команду.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 9.png

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

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 10.png

Стоит также отметить, что в корневой папке с настройками вашего хранилища, вы можете найти папку plugins, а там уже modalforms. Здесь находятся все файлы плагина, поэтому если вы хотите:

  • скорректировать или добавить новую форму, то откройте data.json;

  • попробовать скорректировать общие стили плагина, то откройте style.css

  • ознакомиться как устроен код, но не хотите открывать репозиторий;

Безусловно, не стоит лишний раз нарушать целостность файлов, но такая возможность есть. На Youtube даже можно найти гайды по этой теме в которых говорится, о том, чтобы добавить форму надо открыть data.json и прописать там схему (если честно, в самом начале я на это попался - не допускайте таких глупых ошибок, ведь есть удобный GUI).

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

Обмен формами происходит в формате передачи JSON-сообщений.

Импорт формы

Обмен формами осуществляется через JSON-сообщения.
Импорт формы:

  • Скопируйте текст в формате JSON;

  • Выберите «Импорт формы»;

  • Подтвердите действие.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 11.png

Экспорт формы

Экспорт формы:

  1. Выберите нужную форму.

  2. Нажмите на иконку «Экспорт».

  3. JSON-схема формы сохранится в буфер обмена.

  4. Отправьте её как текстовое сообщение.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 12.png

Создание формы

Если в меню Manage forms пользователь выбрал "Создать форму", то ему становится доступно меню создания новой формы, которое содержит 2 вкладки:

  1. Настройки формы;

  2. Пример кода, который можно вставить в шаблон Templater для получения доступа к вводимым данным.

В данном случае, нас интересует первая вкладка, поэтому рассмотрим ее сейчас детальнее.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 13.png

Пользователю предлагается заполнить такие поля:

  • Обязательные поля:

    • уникальное имя формы, которое мы будем использовать в последующем для обращения к результату работы этой формы при ее вызове в сторонних плагинах (например, в Templater);

    • поля, которые будут обрабатываться пользователем при вызове этой формы;

  • Необязательные поля:

    • заголовок формы, который будет отображаться при открытии формы или в меню управления формами;

    • пользовательский класс, который будет присвоен форме, для последующей кастомизации;

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

После того как будет заполнена минимальная информация - пользователю будут доступны такие опции как:

  • добавить дополнительное поле (количество не ограничено);

  • предпросмотр создаваемой формы (при закрытии, кстати, в правом верхнем углу будет выводиться текст в формате JSON с возвращаемыми данными);

  • сохранить и закрыть форму;

  • отменить сохранение;

Пользовательские поля в модальной форме

При добавлении нового пользовательского поля, предлагается к заполнению информация об этом поле, а именно:

  1. Название поля, по которому мы будем получать доступ к результату вызова формы в сторонних плагинах;

  2. Отображаемый заголовок для этого поля - в случае, если ничего не введено, то в качестве заголовка будет использоваться название поля;

  3. Описание, если вы считаете, что нужно оставить пометку для заполняющего форму;

  4. Тип поля;

  5. Является ли поле скрытым по умолчанию, т.е. будет ли оно отображено при заполнении формы. Может быть полезно в ситуациях, когда срабатывает заданное в форме условие, при котором это поле становится доступным. Если этот переключатель активен, то пользователь не увидит это поле и его содержимое при заполнении формы, но в форму будет записано соответствующее значение;

  6. Переключатель является ли поле обязательным;

  7. Переключатель является ли поле "зависимым" от другого;

  8. Положение поля при отображении в форме, которое можно изменять нажатием на соответствующие стрелочки;

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

  10. Кнопка для удаления поля.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 14.png

Некоторые поля мне хотелось бы рассмотреть немного подробнее, а именно я бы хотел рассмотреть типы полей и особенности их применения, а также особенности использования флага "обязательное поле".

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

Типы пользовательских полей:

text

Добавляет поле для ввода текста. Поле может быть скрытым

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 15.png

number

Добавляет поле для ввода чисел. Это значит, что пользователь не сможет ввести ничего, кроме чисел.

Поле может быть скрытым

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 16.png

tags

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

Стоит отметить, что такое поле, также не может выступать в качестве "скрытого", поскольку подразумевается, что пользователь должен совершить активное действие.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 17.png

email

Добавляет поле для ввода адреса электронной почты, это помогает провалидировать корректность вводимого адреса электронной почты, но речь не идет о полной валидации, а скорее, проверка наличия @ в вводимых данных и отсутствие недопустимых символов в адресе, т.е. не получится ввести test@email,com или test@email@com и т.д.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 18.png

phone

Добавляет поле для ввода номера телефона.

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

Абсолютная лояльность к вводимым данным (спецсимволы, игнорирование регистра и пр) делает это поле на мой взгляд бесполезным.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 19.png

date

Добавляет поле для ввода даты в форме пикера. Возвращает данные в формате ГГГГ-ММ-ДД (2025-06-25)

Поле не может быть выбрано в качестве обязательного, но может быть отмечено как скрытое или зависимое, таким образом, если предположить, что нам нужно отслеживать дату заполнения заметки, например если есть другое текстовое поле, то у нас это все равно не получится :)

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 20.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 20.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 21.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 22.png
Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 22.png

Теперь объяснение: идея, чтобы так работало - безусловно хорошая. Мы могли бы не использовать встроенные JS методы для получения текущей даты или не использовать методы, условного Templater в последующей обработке для получения даты, а передавать ее непосредственно из формы в качестве скрытого поля, но поскольку это поле тоже является "активным", т.е. подразумевает действие пользователя, то так, к сожалению" не сработает. Почему отсутствует дефолтное значение в качестве текущей даты мне не понятно :(

time

Добавляет поле для ввода времени.

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

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 23.png

datetime

Добавляет поле ввода даты и времени. Тут, я думаю, можно обойтись без комментариев

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 24.png

textarea

Добавляет многострочное поле для ввода текста.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 25.png

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

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 26.png

Более подробно о ветвлении в зависимости от условий мы поговорим дальше.

toggle

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

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

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 27.png

note

Добавляет поле для заметок, которое ссылается на заметку в Obsidian. Это поле интересно тем, что пользователь определяет директорию, заметки из которой будут доступны при заполнении формы, т.е. пользователь может выбрать заметку и выбранное название будет передано.

Я использовал этот тип в качестве приложениеобразующего в своей песочнице по контролю финансов, когда только начинал изучать Obsidian

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

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

Может быть обязательным, условным, но не может быть скрытым.

Салфетка/Vangeli/Obsidian 5 Модальные формы/Медиа/Рис. 29.png

folder

Добавляет поле для выбора папки.

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

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

Рис. 30.png

slider

Добавляет поле ввода с числовым ползунком.

Для этого пользователю необходимо определить пределы min и max, среди которых будет осуществляться выбор при вызове формы.

Рис. 31.png

static

Добавляет поле для выбора из выпадающего списка.

У этого типа есть два режима:

  1. Выбор одного из заранее предопределенных вариантов:

    Рис. 32.png
  2. Выбор файла (работает со всеми расширениями доступными в файловом менеджере Obsidian) из выбранной директории:

    Рис. 33.png

dataview

Добавляет поле, заполняемое запросом Dataview.

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

Рис. 34.png
Рис. 34.png

multiselect

Добавляет поле для множественного выбора.

У этого типа есть три режима:

  1. Выбор из заранее предопределенных вариантов:

    Рис. 35.png
  2. Выбор файлов из указанной директории:

    Рис. 36.png
  3. Выбор файлов из массива на основе Dataview запросе:

    Рис. 37.png

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

document block

Добавляет поле для блока документа.

Особенность заключается в том, что пользователь может обращаться к заполненным полям формы для получения кастомной строки. Для этого надо указать form.<field_name> или dv.

Рис. 38.png

Или использовать Dataview Query. Для этого надо указать dv.<particular_method>

На скриншоте я специально допустил ошибку и не убрал пуш toast уведомление, чтобы показать, что если вы где-нибудь ошибетесь, то в целом, ничего страшного и Modal Forms предупредит вас о том, что что-то пошло не так и подскажет где именно это произошло.

Рис. 39.png

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

markdown block

Добавляет поле для блока с разметкой markdown.

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

Рис. 40.png

image

Добавляет поле для загрузки изображений.

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

Возвращает схему с подробной информацией о добавленном изображении (путь, имя, расширение и тд) и помещает изображение в указанную папку.

Рис. 41.png
Рис. 42.png

В свое время я даже создавал issue с запросом сделать вставку изображения из буфера обмена для удобства взаимодействия с картинками, но автор плагина сказала, что это добавило бы много ограничений и в целом, трудно реализуемо. Грустно, конечно, но что поделать?

Еще интересная особенность заключается в том, что при обращении к результату выполнения формы, можно использовать метод .getValue('<field_name>').link, который позволит создать ссылку на изображение.

file

Добавляет поле для загрузки файлов.

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

Рис. 43.png

Условные конструкции

Если в форме добавлено больше 1 поля, то пользователь может создавать условные конструкции, которые будут определять какие поля и при каких обстоятельствах будут выводиться в форме.

Рассмотрим на очень простом примере: нам необходимо проверить готовность пользователя, а затем на основании этого предложить ему заполнить форму.

Создадим два поля: ready с типом toggle и type с типом select в режиме static (заранее определим возможные варианты ответов). Затем нам необходимо для поля type указать, что оно будет доступно только тогда, когда ready = true

Такая форма в виде JSON выглядела бы таким образом:

{
  "title": "Test form",
  "name": "Test form",
  "fields": [
    {
      "name": "ready",
      "label": "",
      "description": "",
      "input": {
        "type": "toggle",
        "allowUnknownValues": false,
        "hidden": false,
        "parentFolder": "02. Utils"
      },
      "isRequired": false
    },
    {
      "name": "type",
      "label": "",
      "description": "",
      "input": {
        "type": "select",
        "allowUnknownValues": false,
        "hidden": false,
        "parentFolder": "Task Tracking",
        "query": "dv.pages().file.name;",
        "multi_select_options": [
          "1",
          "2"
        ],
        "source": "fixed",
        "folder": "Task Tracking",
        "body": "return `Hello **${form.name}**`",
        "filenameTemplate": "image-{{date}}.png",
        "saveLocation": "Салфетка/Vangeli",
        "allowedExtensions": [],
        "options": [
          {
            "value": "human",
            "label": "human"
          },
          {
            "value": "dog",
            "label": "dog"
          }
        ]
      },
      "condition": {
        "dependencyName": "ready",
        "type": "boolean",
        "value": true
      },
      "isRequired": false
    }
  ],
  "version": "1",
  "template": {
    "createCommand": true,
    "parsedTemplate": []
  }
}

Но визуально, все сильно проще:

Рис. 44.png
Рис. 45.png

И по итогу, нам доступна такая форма:

Рис. 46.png

Типы условных конструкций

В зависимости от типа "условного поля" нам доступны следующие типы проверок:

  • isSet (для большинства полей, кроме полей типа toggle)

  • startsWith (для текстовых полей, которые подразумевают ввод данных пользователем)

  • endsWith (для текстовых полей, которые подразумевают ввод данных пользователем)

  • isExactly (для текстовых полей, которые подразумевают ввод данных пользователем)

  • contains (для текстовых полей, которые подразумевают ввод данных пользователем)

  • boolean (для поля с типом toggle)

Рис. 47.png

Получение данных из модальной формы в шаблоне Templater

Я говорил уже, что Modal Forms поддерживает интеграцию со сторонними плагинами, так вот с Templater эта интеграция реализована наиболее тесным образом.

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

Рис. 48.png

В-третьих, в документации автор подробным образом описывает как настроить взаимодействие и получение данных в шаблоне и даже создал демонстрационную песочницу, в которой можно посмотреть как реализовано получение данных (как целиком, так и каких-то отдельных полей)В-чертвертых, в меню управления формами (Manage forms) под каждой формой есть кнопка Open in Template editor, которая позволяет открыть шаблон Templater для конкретной формы.

Рис. 49.png

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

Тем не менее, это всего лишь GUI и все тоже самое можно реализовать самостоятельно, поэтому предлагаю разобраться в этом немного детальнее.

На самом деле, принцип получения данных из формы в шаблоне Templater очень прост:

  1. Нам необходимо инициализировать в шаблоне вызов модальной формы:

    <%* const modalForm = app.plugins.plugins.modalforms.api; %>
    
  2. Затем нам необходимо определить какую форму мы хотим открыть:

    const result = await modalForm.openForm('example-form');
    
  3. Вывести в любом удобном для нас формате значения формы (о всех доступных методах чуть позже):

    tR += result.asFrontmatterString();
    

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

async function openModalForms(formsName) {
    const modalForm = app.plugins.plugins.modalforms.api;
    const result = await modalForm.openForm(formsName);
    return result;
}

module.exports = openModalForms;

А затем, в нашем шаблоне, мы можем использовать вот такую конструкцию:

const result = await tp.user.initModalForms('Test form');

Методы для вывода результатов заполнения формы

Когда вы открываете форму, вы получаете объект FormResult . Этот объект содержит данные формы и некоторые методы, которые помогут вам их обработать. Этот FormResult объект, возвращаемый методом openForm , имеет несколько методов, которые можно использовать для обработки данных формы. Вот краткое описание каждого метода:

  • asFrontmatterString(): этот метод возвращает данные формы в виде строки, которую можно использовать в блоке frontmatter. Он форматирует данные в синтаксисе YAML. Вот пример его использования:

    tR += result.asFrontmatterString({ pick: ["testRow"] });
    
  • asDataviewProperties(): этот метод возвращает данные формы в виде строки со свойствами представления данных. Каждая пара «ключ-значение» в данных формы преобразуется в строку в формате key:: value.

  • getData(): этот метод возвращает копию данных формы. Его можно использовать, когда вам нужно изменить данные формы, не затрагивая исходные данные. В таком случае, мы получаем возможность объект, к которому можем обращаться и получать нужные нам значения

    const result = await tp.user.initModalForms('Test form');
    const allData = result.getData();
    tR += allData.testRow;
    
  • get: возвращает значение данного ключа. Если ключ не существует, возвращает пустую строку "".

    const result = await tp.user.initModalForms('Test form');
    tR += result.get("title");
    
  • getValue: возвращает значение этого ключа, но избавляет от необходимости проверять заполнено ли значение для этого поля:

    const result = await tp.user.initModalForms('Test form');
    tR += result.getValue("title");
    

Как отмечает автор плагина: "Начиная с версии 1.33.0 класс FormResult позволяет получать доступ к значениям полей формы напрямую с помощью property accessors, например result.title или result.listField. Атрибуты свойств эквивалентны вызову метода get, поэтому result.title эквивалентен result.get('title'), но он короче и удобнее. Во всех примерах на этой странице по-прежнему используются более явные способы доступа к значениям, но при желании вы можете использовать атрибуты свойств.

[!ВАЖНО!] Доступ к значениям с помощью property accessors или метода getValue считается более безопасным и предпочтительным способом доступа к значениям. Это связано с тем, что возвращаемые значения заключены в объект ResultValue, который обеспечивает более безопасный и удобный интерфейс для отображения значений в различных форматах."

Доступные команды Modal forms в палитре команд:

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

Рис. 50.png
  1. Перейти в меню создания новой формы;

  2. Импорт существующей формы из буфера обмена;

  3. Редактирование существующей формы, при этом, стоит отметить, что пользователю будет предложено выбрать какую именно форму он будет редактировать

    Рис. 51.png
  4. Создать заметку на основе формы и шаблона Templater, при этом, пользователь может выбрать какую форму он хочет выбрать.

    Рис. 52.png
  5. Создать заметку на основе формы, в этом случае Modal Forms выступает в качестве автономного решения без использования сторонних плагинов, но для этого пользователю нужно заполнить немного больше полей

    Рис. 53.png
  6. Перейти в меню управления существующими формами

    Рис. 54.png

Заключение

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

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

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

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

Буду рад, если в комментариях вы поделитесь практическими задачами, которые хотели бы решать с помощью Obsidian, или опишите интересные решения, которые вам уже удалось реализовать.

Мне также было бы приятно, если бы вы положительно оценили эту статью и участвовали в обсуждении.

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


  1. sven_tesla
    26.06.2025 09:25

    Крутая статья топ просто