Skip to content

Commit

Permalink
Merge pull request #7 from Macegor/develop
Browse files Browse the repository at this point in the history
Доработки маршрутизации
  • Loading branch information
Macegor authored Feb 2, 2025
2 parents 6308c98 + 9790dc3 commit c9367a4
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 16 deletions.
2 changes: 1 addition & 1 deletion packagedef
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Описание.Имя("onecore")
.Версия("0.2.7")
.Версия("0.2.8")
.Автор("Андрей Савадеров (Macegor)")
.АдресАвтора("[email protected]")
.Описание("Фреймворк на движке onescript, созданный для разработки web-приложений любой сложности, используя компонентный подход.")
Expand Down
71 changes: 67 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ OneCore - это web-фреймворк на движке onescript, созда
- [Свойства маршрутов](#свойства-маршрутов)
- [Префиксация маршрутов](#префиксация-маршрутов)
- [Перенаправление](#перенаправление)
- [Произвольные обработчики](#произвольные-обработчики)
- [Дочерние (подчиненные) маршруты](#дочерние-подчиненные-маршруты)
- [Результат примера](#результат-примера)
- [Запуск и отладка](#запуск-и-отладка)
- [Шаблонизатор (jinja)](#шаблонизатор-jinja)
- [Вложение](#вложение)
- [Наследование](#наследование)
- [Формирование](#формирование)
- [Разработка и использование сервисов](#разработка-и-использование-сервисов)
- [Общие объекты](#общие-объекты)
- [Статические файлы](#статические-файлы)
- [Перехватчики (Middleware)](#перехватчики-middleware)
- [Работа с базой данных (ORM)](#работа-с-базой-данных-orm)
Expand Down Expand Up @@ -66,11 +69,20 @@ OneCore - это web-фреймворк на движке onescript, созда
Перед установкой у вас уже должна быть установлена платформа onescript версией не менее 2.0RC5 ветка develop.
Рекомендовано использовать [OVM](https://github.com/oscript-library/ovm) для установки платформы onescript.

**Вариант: 1**

Выполнить консольную команду: ```opm install -l onecore```

**Вариант: 2**

1. Скачать ospx файл с релизов (onecore-х.х.х.ospx)
2. Из каталога "simple" корневого каталога репозитория скопируйте содержимое нужного примера в каталог вашего проекта
3. В каталоге вашего проекта разместите скачанный файл библиотеки (onecore-х.х.х.ospx)
4. Выполнить консольную команду: ```opm i -l -f onecore-x.x.x.ospx``` где "x.x.x" версия фреймворка (библиотеки)
5. Дождаться завершения установки зависимостей, далее для запуска используется команда ```oscript main.os``` или отладчик VSCode
2. В каталоге вашего проекта разместите скачанный файл библиотеки (onecore-х.х.х.ospx)
3. Выполнить консольную команду: ```opm i -l -f onecore-x.x.x.ospx``` где "x.x.x" версия фреймворка (библиотеки)

**Установка примера и запуск**

1. Из каталога "simple" корневого каталога репозитория скопируйте содержимое нужного примера в каталог вашего проекта
2. Дождаться завершения установки зависимостей, далее для запуска используется команда ```oscript main.os``` или отладчик VSCode

[Вернуться к началу](#header)

Expand Down Expand Up @@ -110,6 +122,13 @@ OneCore - это web-фреймворк на движке onescript, созда
Процедура ПриУстановкеПараметровСеанса(ПараметрыСеанса) Экспорт
// Код, выполняемый при создании нового сеанса
// При выполнении данной процедуры будут доступны общие объекты
КонецПроцедуры
Процедура ПриЗапускеПриложения(Отказ) Экспорт
// Код, выполняемый при запуске приложения, отказ отменит запуск,
// так же как и исключение
// При выполнении данной процедуры будут доступны общие объекты
КонецПроцедуры
```

Expand Down Expand Up @@ -346,6 +365,33 @@ OneCore - это web-фреймворк на движке onescript, созда

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

###### Произвольные обработчики

По умолчанию в представлениях при обработке HTTP-запросов вызываются методы, соответствующие HTTP-методам (GET, POST, PUT, DELETE). Это создает ограничение при использовании одного файла для обработки нескольких связанных операций, например, для создания, обновления и удаления записи. Для расширения функциональности представлений реализована возможность указывать для маршрута один или несколько пользовательских обработчиков. Это достигается путем сопоставления HTTP-метода с именем процедуры, которая будет вызываться при обработке запроса.

Пример использования:

```bsl
Маршруты.Добавить("/persons/delete/<Число:ИдентификаторПользователя>", "ФизическиеЛица.Элемент").Имя("Удаление").Обработчик(МетодыHTTP.GET, "УдалитьЭлемент");
```

Согласно примеру при запросе на адрес ```/persons/delete/1``` будет вызвана процедура ```УдалитьЭлемент``` представления ```ФизическиеЛица.Элемент```.

###### Дочерние (подчиненные) маршруты

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

```bsl
МаршрутыФизЛица = Маршруты.Добавить("/persons", "ФизическиеЛица.Список").Имя("ФизЛица"); // Адрес: /persons Имя: "Ядро.ФизЛица"
МаршрутыФизЛица.Дочерний("/create", "ФизическиеЛица.Элемент").Имя("Создание"); // Адрес: /persons/create Имя: "Ядро.ФизЛица.Создание"
МаршрутыФизЛица.Дочерний("/<Число:ИдентификаторПользователя>", "ФизическиеЛица.Элемент").Имя("Элемент"); // Адрес: /persons/<Число:ИдентификаторПользователя> Имя: "Ядро.ФизЛица.Элемент"
МаршрутыФизЛица.Дочерний("/delete/<Число:ИдентификаторПользователя>", "ФизическиеЛица.Элемент").Имя("Удаление").Обработчик(МетодыHTTP.GET, "УдалитьЭлемент"); // Адрес: /persons/delete/<Число:ИдентификаторПользователя> Имя: "Ядро.ФизЛица.Удаление"
```

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

**Важно**: дочерний маршрут наследует адрес, имя и ключ представления родительского маршрута (если явно не указано иное).

##### Результат примера

Согласно тому, что мы указали, сервер, при обращении клиента к корневому адресу, будет переадресовывать выполнение в наш контроллер. Процедура "Добавить" принимает в себя 2 параметра, первый - это шаблон адреса, второй - строковый путь к объекту обработчика запроса через точку, при этом, если бы у нас объект обработчика находился не в корневом каталоге "Представления", а, например, в каталоге "Тестирование", тогда указание маршрута выглядело бы так ```Маршруты.Добавить("/", "Тестирование.Приветствие");```.
Expand Down Expand Up @@ -596,6 +642,23 @@ OneCore - это web-фреймворк на движке onescript, созда

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

#### Общие объекты

В модулях сервисов, компонентов, представлений и моделей, а также любых других объектов, созданных функцией "СоздатьОбъект" объекта "МенеджерОбъектов", автоматически будут устанавливаться объекты в одноименные глобальные переменные модуля. Доступные глобальные объекты:

- МенеджерОбъектов
- Маршрутизатор
- МенеджерСеансов
- МенеджерORM

То есть при объявлении глобальной переменной "Маршрутизатор" в неё будет помещен глобальный объект "Маршрутизатор":

```bsl
Перем Маршрутизатор, МенеджерСеансов;
```

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

[Вернуться к началу](#header)

### Статические файлы
Expand Down
7 changes: 5 additions & 2 deletions src/Классы/КоллекцияМаршрутов.os
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@

Если Компонент <> Неопределено И НЕ Статический Тогда

КлючОбъекта = СтрШаблон("%1.%2.%3", Компонент.Имя(), "Представления", КлючОбъекта);
Если НЕ СтрНайти(КлючОбъекта, ".Представления.") Тогда
КлючОбъекта = СтрШаблон("%1.%2.%3", Компонент.Имя(), "Представления", КлючОбъекта);
КонецЕсли;

Адрес = ?(ПрефиксКомпонента, СтрШаблон("/%1%2", Компонент.ИмяЛатинское(), Адрес), Адрес);

Если Адрес <> "/" Тогда
Expand All @@ -81,7 +84,7 @@
Возврат Неопределено;
КонецЕсли;

НовыйОбъект = Новый Маршрут(Адрес, КлючОбъекта, Компонент);
НовыйОбъект = Новый Маршрут(ЭтотОбъект, Адрес, КлючОбъекта, Компонент);
НовыйОбъект.ТипОбъекта(Тип);
НовыйОбъект.Статический(Статический);
НовыйОбъект.КоличествоЧастейМаршрута(СтрРазделить(Адрес, "/", Ложь).Количество());
Expand Down
10 changes: 8 additions & 2 deletions src/Классы/Компонент.os
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Перем ПутьКомпонента;
Перем МодульКомпонента;
Перем МоделиКомпонента;
Перем МенеджерОбъектов;

Процедура ПриСозданииОбъекта(ИмяКомпонента, ИмяКомпонентаЛатинское, Отказ = Ложь)

Expand Down Expand Up @@ -43,12 +44,17 @@

КонецПроцедуры

Процедура ВыполнитьОбработкуПриЗапуске() Экспорт
Процедура ВыполнитьОбработкуПриЗапуске(Отказ = Ложь) Экспорт

ИмяМетода = "ПриЗапускеПриложения";

МенеджерОбъектов.ПодключитьОбщиеОбъектыКОбъекту(МодульКомпонента);

Если Рефлексия.МетодСуществует(МодульКомпонента, ИмяМетода) Тогда
Рефлексия.ВызватьМетод(МодульКомпонента, ИмяМетода);
МассивПараметров = Новый Массив();
МассивПараметров.Добавить(Отказ);
Рефлексия.ВызватьМетод(МодульКомпонента, ИмяМетода, МассивПараметров);
Отказ = МассивПараметров[0];
КонецЕсли;

КонецПроцедуры
Expand Down
42 changes: 40 additions & 2 deletions src/Классы/Маршрут.os
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

Перем Коллекция;
Перем РодительскийМаршрут;
Перем Имя;
Перем Компонент;
Перем АдресМаршрута;
Expand All @@ -8,14 +10,17 @@
Перем КоличествоЧастейМаршрута;
Перем СодержитПараметры;
Перем Свойства;
Перем ПользовательскиеОбработчики;

Процедура ПриСозданииОбъекта(Адрес, Ключ, ПарКомпонент = Неопределено)
Процедура ПриСозданииОбъекта(ОбъектКоллекции, Адрес, Ключ, ПарКомпонент = Неопределено)

АдресМаршрута = Адрес;
КлючОбъекта = Ключ;
Статический = Ложь;
Свойства = Новый Структура();
ПользовательскиеОбработчики = Новый Структура();
Компонент = ПарКомпонент;
Коллекция = ОбъектКоллекции;

КонецПроцедуры

Expand All @@ -31,6 +36,10 @@
Возврат Свойства;
КонецФункции

Функция ПользовательскиеОбработчики() Экспорт
Возврат ПользовательскиеОбработчики;
КонецФункции

Функция Имя(Значение = Неопределено) Экспорт

Если Значение = Неопределено Тогда
Expand All @@ -41,7 +50,12 @@
ВызватьИсключение "Ожидается тип Строка";
КонецЕсли;

Имя = СтрШаблон("%1.%2", Компонент.Имя(), Значение);
Если РодительскийМаршрут = Неопределено Тогда
Имя = СтрШаблон("%1.%2", Компонент.Имя(), Значение);
Иначе
Имя = СтрШаблон("%1.%2", РодительскийМаршрут.Имя(), Значение);
КонецЕсли;

Возврат ЭтотОбъект;

КонецФункции
Expand Down Expand Up @@ -117,4 +131,28 @@
Свойства.Вставить(Ключ, Значение);
Возврат ЭтотОбъект;

КонецФункции

Функция Обработчик(Метод, ИмяПроцедуры) Экспорт
ПользовательскиеОбработчики.Вставить(Метод, ИмяПроцедуры);
Возврат ЭтотОбъект;
КонецФункции

Функция Дочерний(Адрес, Ключ = Неопределено) Экспорт

ДочернийМаршрут = Неопределено;

КлючДочернего = ?(Ключ = Неопределено, КлючОбъекта, Ключ);
АдресДочернего = СтрШаблон("%1/%2", АдресМаршрута, ?(СтрНачинаетсяС(Адрес, "/"), Прав(Адрес, СтрДлина(Адрес) - 1), Адрес));

ДочернийМаршрут = Коллекция.Добавить(АдресДочернего, КлючДочернего);

Если ДочернийМаршрут <> Неопределено Тогда
СвойстваПодчиненногоМаршрута = Коллекции.СкопироватьСтруктуру(Свойства);
Рефлексия.УстановитьСвойство(ДочернийМаршрут, "РодительскийМаршрут", ЭтотОбъект);
Рефлексия.УстановитьСвойство(ДочернийМаршрут, "Свойства", СвойстваПодчиненногоМаршрута);
КонецЕсли;

Возврат ДочернийМаршрут;

КонецФункции
Loading

0 comments on commit c9367a4

Please sign in to comment.