updated htmx+templatepro sample

This commit is contained in:
Daniele Teti 2024-08-24 16:32:38 +02:00
parent 1ae17451f4
commit 5b17a44962
33 changed files with 1056 additions and 530 deletions

3
.gitignore vendored
View File

@ -146,4 +146,5 @@ samples/WineCellarSample/winecellarclient_mobile/Android/Debug/WineCellarMobileC
samples/apachemodule/Apache24/logs/httpd.pid
samples/session_file_based/Win32/DEBUG/sessions/
unittests/general/UnitTestReports/
lib/sempare-delphi-template-engine
lib/sempare-delphi-template-engine
*.tpcu

View File

@ -164,6 +164,19 @@ type
); override;
end;
TUnitTemplateProHelpersDeclarationCommand = class(TCustomCommand)
public
procedure ExecuteInterface(
Section: TStringBuilder;
Model: TJSONObject
); override;
procedure ExecuteImplementation(
Section: TStringBuilder;
Model: TJsonObject
); override;
end;
TUnitFooterCommand = class(TCustomCommand)
public
@ -305,6 +318,12 @@ begin
.AppendLine(' MVCFramework.DotEnv,')
.AppendLine(' MVCFramework.Commons,')
.AppendLine(' MVCFramework.Serializer.Commons,');
if Model.B[TConfigKey.program_ssv_templatepro] then
begin
Section
.AppendLine(' MVCFramework.View.Renderers.TemplatePro,');
end;
if Model.B[TConfigKey.program_ssv_mustache] then
begin
Section
@ -758,11 +777,19 @@ begin
Section
.AppendLine(' System.IOUtils,')
.AppendLine(' MVCFramework.Commons,');
if Model.B[TConfigKey.program_ssv_templatepro] then
begin
Section
.AppendLine(' MVCFramework.View.Renderers.TemplatePro,')
end;
if Model.B[TConfigKey.program_ssv_mustache] then
begin
Section
.AppendLine(' MVCFramework.View.Renderers.Mustache,')
end;
Section
.AppendLine(' MVCFramework.Middleware.ActiveRecord,')
.AppendLine(' MVCFramework.Middleware.StaticFiles,')
@ -807,6 +834,16 @@ begin
.AppendLine(' FMVC.AddController(' + Model[TConfigKey.controller_classname] + ');')
.AppendLine(' // Controllers - END')
.AppendLine;
if Model.B[TConfigKey.program_ssv_templatepro] then
begin
Section
.AppendLine(' // Server Side View')
.AppendLine(' FMVC.SetViewEngine(TMVCTemplateProViewEngine);')
.AppendLine(' // Server Side View - END')
.AppendLine;
end;
if Model.B[TConfigKey.program_ssv_mustache] then
begin
Section
@ -815,6 +852,8 @@ begin
.AppendLine(' // Server Side View - END')
.AppendLine;
end;
Section
.AppendLine(' // Middleware');
@ -1006,6 +1045,9 @@ begin
.AppendLine(' // UseConsoleLogger defines if logs must be emitted to also the console (if available).')
.AppendLine(' UseConsoleLogger := True;')
.AppendLine()
.AppendLine(' // MVCUseTemplatesCache allows to cache compiled templates on disk for a faster future execution (if engine supports it).')
.AppendLine(' MVCUseTemplatesCache := True;')
.AppendLine()
.AppendLine(' LogI(''** DMVCFramework Server ** build '' + DMVCFRAMEWORK_VERSION);');
if Model.B[TConfigKey.program_dotenv] then
@ -1341,4 +1383,81 @@ begin
end;
{ TUnitTemplateProHelpersDeclarationCommand }
procedure TUnitTemplateProHelpersDeclarationCommand.ExecuteImplementation(
Section: TStringBuilder; Model: TJsonObject);
begin
inherited;
Section
.AppendLine('implementation')
.AppendLine
.AppendLine('uses')
.AppendLine(' TemplatePro, System.SysUtils;')
.AppendLine
.AppendLine
.AppendLine('function MyHelper1(const Value: TValue; const Parameters: TArray<string>): string;')
.AppendLine('begin')
.AppendLine(' Result := Value.ToString + '' (I''''m The MyHelper1)'';')
.AppendLine('end;')
.AppendLine
.AppendLine('function MyHelper2(const Value: TValue; const Parameters: TArray<string>): string;')
.AppendLine('begin')
.AppendLine(' Result := Value.ToString + '' (I''''m The MyHelper2)'';')
.AppendLine('end;')
.AppendLine
.AppendLine
.AppendLine('procedure TemplateProContextConfigure;')
.AppendLine('begin')
.AppendLine(' TTProConfiguration.OnContextConfiguration := procedure(const CompiledTemplate: ITProCompiledTemplate)')
.AppendLine(' begin')
.AppendLine(' // These filters will be available to the TemplatePro views as if they were the standard ones')
.AppendLine(' CompiledTemplate.AddFilter(''MyHelper1'', MyHelper1);')
.AppendLine(' CompiledTemplate.AddFilter(''MyHelper2'', MyHelper2);')
.AppendLine
.AppendLine(' CompiledTemplate.OnGetValue :=')
.AppendLine(' procedure(const DataSource, Members: string; var Value: TValue; var Handled: Boolean)')
.AppendLine(' begin')
.AppendLine(' if SameText(DataSource, ''ext1'') then')
.AppendLine(' begin')
.AppendLine(' if Members.IsEmpty then')
.AppendLine(' begin')
.AppendLine(' Value := ''External Value Ext1''')
.AppendLine(' end')
.AppendLine(' else')
.AppendLine(' begin')
.AppendLine(' Value := ''Reading ext1.'' + Members;')
.AppendLine(' end;')
.AppendLine(' Handled := True;')
.AppendLine(' end;')
.AppendLine(' end')
.AppendLine(' end;')
.AppendLine('end;')
.AppendLine
.AppendLine
.AppendLine('end.');
end;
procedure TUnitTemplateProHelpersDeclarationCommand.ExecuteInterface(
Section: TStringBuilder; Model: TJSONObject);
begin
inherited;
CheckFor(TConfigKey.program_ssv_mustache, Model);
CheckFor(TConfigKey.templatepro_helpers_unit_name, Model);
Section
.AppendLine('unit ' + Model[TConfigKey.templatepro_helpers_unit_name] + ';')
.AppendLine
.AppendLine('interface')
.AppendLine
.AppendLine('uses')
.AppendLine(' System.Rtti;')
.AppendLine
.AppendLine('function MyHelper1(const Value: TValue; const Parameters: TArray<string>): string;')
.AppendLine('function MyHelper2(const Value: TValue; const Parameters: TArray<string>): string;')
.AppendLine
.AppendLine
.AppendLine('procedure TemplateProContextConfigure;')
.AppendLine;
end;
end.

View File

@ -34,6 +34,7 @@ procedure FillControllerTemplates(Gen: TMVCCodeGenerator);
procedure FillWebModuleTemplates(Gen: TMVCCodeGenerator);
procedure FillWebModuleDFMTemplates(Gen: TMVCCodeGenerator);
procedure FillJSONRPCTemplates(Gen: TMVCCodeGenerator);
procedure FillTemplateProTemplates(Gen: TMVCCodeGenerator);
procedure FillMustacheTemplates(Gen: TMVCCodeGenerator);
procedure FillEntitiesTemplates(Gen: TMVCCodeGenerator);
procedure FillServicesTemplates(Gen: TMVCCodeGenerator);
@ -90,6 +91,13 @@ begin
]);
end;
procedure FillTemplateProTemplates(Gen: TMVCCodeGenerator);
begin
Gen.Commands.AddRange([
TUnitTemplateProHelpersDeclarationCommand.Create
]);
end;
procedure FillServicesTemplates(Gen: TMVCCodeGenerator);
begin
Gen.Commands.AddRange([

View File

@ -58,10 +58,12 @@ type
program_msheap='program.msheap';
program_sqids='program.sqids';
program_dotenv='program.dotenv';
program_ssv_templatepro='program.ssv.templatepro';
program_ssv_mustache='program.ssv.mustache';
program_service_container_generate = 'program.service.container.generate';
program_service_container_unit_name = 'program.service.container.unit_name';
mustache_helpers_unit_name = 'mustache.helpers_unit_name';
templatepro_helpers_unit_name = 'templatepro.helpers_unit_name';
controller_unit_name='controller.unit_name';
controller_classname= 'controller.classname';
controller_index_methods_generate= 'controller.index_methods.generate';

View File

@ -504,9 +504,9 @@ object frmDMVCNewProject: TfrmDMVCNewProject
end
object Panel2: TPanel
Left = 0
Top = 374
Top = 400
Width = 308
Height = 215
Height = 189
Anchors = [akLeft, akBottom]
BevelOuter = bvNone
Caption = 'Panel2'
@ -516,18 +516,18 @@ object frmDMVCNewProject: TfrmDMVCNewProject
TabOrder = 5
DesignSize = (
308
215)
189)
object gbControllerUnitOptions: TGroupBox
Left = 8
Top = 29
Left = 12
Top = 0
Width = 296
Height = 177
Height = 184
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = 'Controller Unit Options'
TabOrder = 0
DesignSize = (
296
177)
184)
object lblClassName: TLabel
Left = 16
Top = 126
@ -592,19 +592,6 @@ object frmDMVCNewProject: TfrmDMVCNewProject
WordWrap = True
end
end
object chkCreateControllerUnit: TCheckBox
Left = 24
Top = 4
Width = 241
Height = 17
Anchors = [akLeft, akTop, akRight]
Caption = 'Create Controller Unit'
Checked = True
State = cbChecked
TabOrder = 1
Visible = False
OnClick = chkCreateControllerUnitClick
end
end
object GroupBox1: TGroupBox
Left = 314
@ -779,16 +766,17 @@ object frmDMVCNewProject: TfrmDMVCNewProject
end
object chkMustache: TCheckBox
Left = 24
Top = 311
Top = 331
Width = 225
Height = 17
Anchors = [akLeft, akRight, akBottom]
Caption = 'Use Mustache as Server Side View engine'
TabOrder = 10
OnClick = chkMustacheClick
end
object chkServicesContainer: TCheckBox
Left = 24
Top = 330
Top = 351
Width = 225
Height = 17
Anchors = [akLeft, akRight, akBottom]
@ -799,7 +787,7 @@ object frmDMVCNewProject: TfrmDMVCNewProject
end
object chkSqids: TCheckBox
Left = 24
Top = 350
Top = 371
Width = 225
Height = 17
Anchors = [akLeft, akRight, akBottom]
@ -825,6 +813,16 @@ object frmDMVCNewProject: TfrmDMVCNewProject
'SnakeCase (foo_bar)')
TabOrder = 13
end
object chkTemplatePro: TCheckBox
Left = 24
Top = 312
Width = 245
Height = 17
Anchors = [akLeft, akRight, akBottom]
Caption = 'Use TemplatePro as Server Side View engine'
TabOrder = 14
OnClick = chkTemplateProClick
end
object ApplicationEvents: TApplicationEvents
OnIdle = ApplicationEventsIdle
Left = 264

View File

@ -72,7 +72,6 @@ type
edtControllerClassName: TEdit;
chkCreateActionFiltersMethods: TCheckBox;
chkCreateCRUDMethods: TCheckBox;
chkCreateControllerUnit: TCheckBox;
Shape1: TShape;
GroupBox1: TGroupBox;
chkAnalyticsMiddleware: TCheckBox;
@ -102,7 +101,7 @@ type
chkServicesContainer: TCheckBox;
chkSqids: TCheckBox;
rgNameCase: TRadioGroup;
procedure chkCreateControllerUnitClick(Sender: TObject);
chkTemplatePro: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure Image1Click(Sender: TObject);
procedure lblBookMouseEnter(Sender: TObject);
@ -117,6 +116,8 @@ type
procedure lblPATREONClick(Sender: TObject);
procedure lblPATREONMouseEnter(Sender: TObject);
procedure lblPATREONMouseLeave(Sender: TObject);
procedure chkMustacheClick(Sender: TObject);
procedure chkTemplateProClick(Sender: TObject);
private
{ Private declarations }
fModel: TJsonObject;
@ -176,12 +177,16 @@ begin
end;
end;
procedure TfrmDMVCNewProject.chkCreateControllerUnitClick(Sender: TObject);
procedure TfrmDMVCNewProject.chkMustacheClick(Sender: TObject);
begin
chkCreateIndexMethod.Enabled := chkCreateControllerUnit.Checked;
chkCreateActionFiltersMethods.Enabled := chkCreateControllerUnit.Checked;
chkCreateCRUDMethods.Enabled := chkCreateControllerUnit.Checked;
edtControllerClassName.Enabled := chkCreateControllerUnit.Checked;
if chkMustache.Checked then
chkTemplatePro.Checked := False;
end;
procedure TfrmDMVCNewProject.chkTemplateProClick(Sender: TObject);
begin
if chkTemplatePro.Checked then
chkMustache.Checked := False;
end;
procedure TfrmDMVCNewProject.FormCreate(Sender: TObject);
@ -327,7 +332,7 @@ end;
function TfrmDMVCNewProject.GetCreateControllerUnit: boolean;
begin
Result := chkCreateControllerUnit.Checked;
Result := True;
end;
function TfrmDMVCNewProject.GetCreateCRUDMethods: boolean;
@ -344,6 +349,7 @@ begin
fModel.B[TConfigKey.program_sqids] := chkSqids.Checked;
fModel.B[TConfigKey.program_dotenv] := chkCustomConfigDotEnv.Checked;
fModel.B[TConfigKey.program_ssv_mustache] := chkMustache.Checked;
fModel.B[TConfigKey.program_ssv_templatepro] := chkTemplatePro.Checked;
fModel.B[TConfigKey.program_service_container_generate] := chkServicesContainer.Checked;
fModel.S[TConfigKey.program_service_container_unit_name] := 'TBA';
fModel.S[TConfigKey.controller_unit_name] := 'TBA';

View File

@ -95,17 +95,19 @@ begin
ServicesUnit: IOTAModule;
WebModuleUnit: IOTAModule;
MustacheHelperUnit: IOTAModule;
TemplateProHelperUnit: IOTAModule;
ControllerCreator: IOTACreator;
EntityCreator: IOTACreator;
JSONRPCUnitCreator: IOTACreator;
ServicesUnitCreator: IOTACreator;
MustacheHelpersUnitCreator: IOTACreator;
HelpersUnitCreator: IOTACreator;
WebModuleCreator: IOTAModuleCreator;
lProjectSourceCreator: IOTACreator;
lJSONRPCUnitName: string;
lServicesUnitName: string;
lJSON: TJSONObject;
lMustacheHelpersUnitName: string;
lTemplateProHelpersUnitName: string;
lEntityUnitName: string;
EntityUnit: IOTAModule;
begin
@ -202,16 +204,17 @@ begin
end;
lMustacheHelpersUnitName := '';
// Create Mustache Helpers Unit
if lJSON.B[TConfigKey.program_ssv_mustache] then
begin
MustacheHelpersUnitCreator := TNewGenericUnitFromTemplate.Create(
HelpersUnitCreator := TNewGenericUnitFromTemplate.Create(
lJSON,
FillMustacheTemplates,
TConfigKey.mustache_helpers_unit_name,
APersonality);
MustacheHelperUnit := ModuleServices.CreateModule(MustacheHelpersUnitCreator);
MustacheHelperUnit := ModuleServices.CreateModule(HelpersUnitCreator);
ChangeIOTAModuleFileNamePrefix(MustacheHelperUnit, 'MustacheHelpers');
lMustacheHelpersUnitName := GetUnitName(MustacheHelperUnit.FileName);
lJSON.S[TConfigKey.mustache_helpers_unit_name] := lMustacheHelpersUnitName;
@ -221,6 +224,25 @@ begin
end;
end;
lTemplateProHelpersUnitName := '';
// Create TemplatePro Helpers Unit
if lJSON.B[TConfigKey.program_ssv_templatepro] then
begin
HelpersUnitCreator := TNewGenericUnitFromTemplate.Create(
lJSON,
FillTemplateProTemplates,
TConfigKey.templatepro_helpers_unit_name,
APersonality);
TemplateProHelperUnit := ModuleServices.CreateModule(HelpersUnitCreator);
ChangeIOTAModuleFileNamePrefix(TemplateProHelperUnit, 'TemplateProHelpers');
lTemplateProHelpersUnitName := GetUnitName(TemplateProHelperUnit.FileName);
lJSON.S[TConfigKey.templatepro_helpers_unit_name] := lTemplateProHelpersUnitName;
if Project <> nil then
begin
Project.AddFile(TemplateProHelperUnit.FileName, True);
end;
end;
// Create Webmodule Unit
WebModuleCreator := TNewWebModuleUnitEx.Create(

View File

@ -24,6 +24,26 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimARM64' and '$(Base)'=='true') or '$(Base_iOSSimARM64)'!=''">
<Base_iOSSimARM64>true</Base_iOSSimARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSXARM64' and '$(Base)'=='true') or '$(Base_OSXARM64)'!=''">
<Base_OSXARM64>true</Base_OSXARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -78,6 +98,26 @@
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSXARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -1053,7 +1093,11 @@
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimARM64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="OSXARM64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
<Platform value="Win64x">False</Platform>

View File

@ -24,6 +24,26 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimARM64' and '$(Base)'=='true') or '$(Base_iOSSimARM64)'!=''">
<Base_iOSSimARM64>true</Base_iOSSimARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSXARM64' and '$(Base)'=='true') or '$(Base_OSXARM64)'!=''">
<Base_OSXARM64>true</Base_OSXARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -82,6 +102,26 @@
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
<EnabledSysJars>activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSXARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>false</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -1060,7 +1100,11 @@
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimARM64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="OSXARM64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
<Platform value="Win64x">False</Platform>

View File

@ -24,6 +24,16 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimARM64' and '$(Base)'=='true') or '$(Base_iOSSimARM64)'!=''">
<Base_iOSSimARM64>true</Base_iOSSimARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -89,6 +99,18 @@
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -1092,6 +1114,8 @@
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimARM64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>

View File

@ -118,7 +118,9 @@ contains
MVCFramework.Signal in '..\..\sources\MVCFramework.Signal.pas',
MVCFramework.Serializer.Text in '..\..\sources\MVCFramework.Serializer.Text.pas',
MVCFramework.Container in '..\..\sources\MVCFramework.Container.pas',
sqids in '..\..\sources\sqids.pas';
sqids in '..\..\sources\sqids.pas',
MVCFramework.View.Renderers.TemplatePro in '..\..\sources\MVCFramework.View.Renderers.TemplatePro.pas',
TemplatePro in '..\..\sources\TemplatePro.pas';
end.

View File

@ -24,6 +24,26 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimARM64' and '$(Base)'=='true') or '$(Base_iOSSimARM64)'!=''">
<Base_iOSSimARM64>true</Base_iOSSimARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSX64' and '$(Base)'=='true') or '$(Base_OSX64)'!=''">
<Base_OSX64>true</Base_OSX64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='OSXARM64' and '$(Base)'=='true') or '$(Base_OSXARM64)'!=''">
<Base_OSXARM64>true</Base_OSXARM64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -90,6 +110,26 @@
<BT_BuildType>Debug</BT_BuildType>
<EnabledSysJars>activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_BundleId>$(MSBuildProjectName)</VerInfo_BundleId>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone &amp; iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers</VerInfo_Keys>
<VerInfo_UIDeviceFamily>iPhoneAndiPad</VerInfo_UIDeviceFamily>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSX64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_OSXARM64)'!=''">
<VerInfo_Keys>CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple&apos;s speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface</VerInfo_Keys>
<BT_BuildType>Debug</BT_BuildType>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -222,6 +262,8 @@
<DCCReference Include="..\..\sources\MVCFramework.Serializer.Text.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.Container.pas"/>
<DCCReference Include="..\..\sources\sqids.pas"/>
<DCCReference Include="..\..\sources\MVCFramework.View.Renderers.TemplatePro.pas"/>
<DCCReference Include="..\..\sources\TemplatePro.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -1134,7 +1176,11 @@
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimARM64">False</Platform>
<Platform value="Linux64">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="OSXARM64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
<Platform value="Win64x">False</Platform>

View File

@ -11,6 +11,7 @@ type
TWebSiteController = class(TMVCController)
protected
function GeneratePeopleListAsCSV: String;
procedure OnBeforeAction(AContext: TWebContext; const AActionName: string; var AHandled: Boolean); override;
public
[MVCPath]
[MVCHTTPMethods([httpGET])]
@ -24,6 +25,7 @@ type
[MVCHTTPMethods([httpPOST])]
[MVCConsumes(TMVCMediaType.APPLICATION_FORM_URLENCODED)]
procedure SavePerson(
const [MVCFromContentField('guid','')] GUID: String;
const [MVCFromContentField('first_name')] FirstName: String;
const [MVCFromContentField('last_name')] LastName: String;
const [MVCFromContentField('age', 0)] Age: Integer;
@ -32,7 +34,7 @@ type
[MVCPath('/delete/($guid)')]
[MVCHTTPMethods([httpDELETE])]
procedure DeletePerson(const guid: string);
function DeletePerson(const guid: string): String;
[MVCPath('/new')]
[MVCHTTPMethods([httpGET])]
@ -67,14 +69,14 @@ implementation
uses DAL, System.SysUtils, Web.HTTPApp;
procedure TWebSiteController.DeletePerson(const guid: string);
function TWebSiteController.DeletePerson(const guid: string): String;
var
LDAL: IPeopleDAL;
begin
LDAL := TServicesFactory.GetPeopleDAL;
LDAL.DeleteByGUID(GUID);
Context.Response.HXSetLocation('/people');
RenderStatusMessage(HTTP_STATUS.OK);
Context.Response.HXSetReplaceUrl('/people');
Result := PeopleSearch('');
end;
function TWebSiteController.EditPerson(guid: string): String;
@ -140,13 +142,19 @@ begin
lDevices := LDAL.GetDevicesList;
try
ViewData['deviceslist'] := lDevices;
ViewData['ishtmx'] := Context.Request.IsHTMX;
Result := Page(['editperson']);
finally
lDevices.Free;
end;
end;
procedure TWebSiteController.OnBeforeAction(AContext: TWebContext;
const AActionName: string; var AHandled: Boolean);
begin
inherited;
ViewData['ishtmx'] := AContext.Request.IsHTMX;
end;
function TWebSiteController.PeopleSearch(const SearchText: String): String;
var
LDAL: IPeopleDAL;
@ -157,7 +165,6 @@ begin
lPeople := LDAL.GetPeople(SearchText);
try
ViewData['people'] := lPeople;
ViewData['ishtmx'] := Context.Request.IsHTMX;
if Context.Request.IsHTMX then
begin
if SearchText.IsEmpty then
@ -166,13 +173,14 @@ begin
Context.Response.HXSetPushUrl('/people?q=' + SearchText);
end;
ViewData['q'] := SearchText;
Result := PageFragment(['people_list']);
Result := Page(['people_list']);
finally
lPeople.Free;
end;
end;
procedure TWebSiteController.SavePerson(
const GUID: String;
const FirstName: String;
const LastName: String;
const Age: Integer;
@ -187,6 +195,8 @@ begin
end;
LPeopleDAL := TServicesFactory.GetPeopleDAL;
if not GUID.IsEmpty then
LPeopleDAL.DeleteByGUID(GUID);
LPeopleDAL.AddPerson(FirstName, LastName, Age, Devices);
Context.Response.HXSetRedirect('/people');
end;

View File

@ -1 +1 @@
[{"first_name":"Bruce","last_name":"Banner","age":56,"items":"smartphone,dumbphone","guid":"2290EE213DFB4855894A3FC91FE52C17"},{"first_name":"Reed","last_name":"Richards","age":45,"items":"laptop,smartphone","guid":"298CE047B4C24D67B29710BF4ABE290C"},{"first_name":"Scott","last_name":"Summers","age":54,"items":"desktop","guid":"3DACB879E83749EDA68389EBA2286A13"},{"first_name":"Daniele","last_name":"Teti","age":40,"items":"dumbphone,laptop","guid":"C2C002A595694C7CBD3CA1F3123F0EEB"},{"first_name":"Sue","last_name":"Storm","age":32,"items":"smartphone,laptop","guid":"4E74A300ECE4493B8287630A0715AC17"},{"first_name":"Tony","last_name":"Stark","age":45,"items":"smartphone,laptop,desktop","guid":"203384AF26564677AD99AEFB30DA2B66"},{"first_name":"Peter","last_name":"Parker","age":22,"items":"dumbphone,desktop","guid":"DFBF50FEC4504B6AA4128250994BD7AE"}]
[{"first_name":"Bruce","last_name":"Banner","age":56,"items":"smartphone,dumbphone","guid":"2290EE213DFB4855894A3FC91FE52C17"},{"first_name":"Scott","last_name":"Summers","age":54,"items":"desktop","guid":"3DACB879E83749EDA68389EBA2286A13"},{"first_name":"Daniele","last_name":"Teti","age":40,"items":"dumbphone,laptop","guid":"C2C002A595694C7CBD3CA1F3123F0EEB"},{"first_name":"Sue","last_name":"Storm","age":32,"items":"smartphone,laptop","guid":"4E74A300ECE4493B8287630A0715AC17"},{"first_name":"Tony","last_name":"Stark","age":45,"items":"smartphone,laptop,desktop","guid":"203384AF26564677AD99AEFB30DA2B66"},{"first_name":"Reed","last_name":"Richards","age":99,"items":"smartphone,laptop","guid":"08D40CEAF6AA488B8F883F763024A7C2"}]

View File

@ -1,7 +1,7 @@
{{if(!ishtmx)}}
{{include("partials/header.html")}}
{{endif}}
<form class="form form-horizontal" id="myForm" name="myForm" hx-post="/people">
<form class="form form-horizontal" id="myForm" name="myForm" hx-post="/people" hx-target="#main">
<input type="hidden" value="{{:person.guid}}" name="guid">
<div class="row">
<div class="col">
@ -41,7 +41,7 @@
<label for="items" class="col-sm-10 control-label">Devices</label>
<select id="items" name="items" multiple class="form-control">
{{loop(deviceslist) as device}}
<option value="{{:device.devicename}}" {{if(device.selected)}}selected{{endif}}>{{:device.devicename}}</option>
<option value="{{:device.devicename}}" {{if(device.selected)}}selected{{endif}}>{{:device.devicename|capitalize}}</option>
{{endloop}}
</select>
<span style="font-size: 80%">(Ctrl+Click to select multiple devices)</span>
@ -51,9 +51,9 @@
<div class="row" style="padding-top:2rem">
<div class="col">
<button type="button" class="btn btn-secondary btn-block w-100" onclick="history.back()">Return to the list</button>
<button type="button" class="btn btn-secondary btn-block w-100" hx-get="/people">Return to the list</button>
</div>
<div class="col offset-4">
<div class="col offset-5">
</div>
<div class="col">
<button type="submit" class="btn btn-primary btn-block w-100">Save</button>
@ -63,6 +63,7 @@
<button
type="button"
hx-confirm="Are you sure you wish to delete user?"
hx-target="#main"
hx-delete="/people/delete/{{:person.guid}}"
class="btn btn-danger btn-block w-100">
Delete

View File

@ -7,7 +7,7 @@
<p>{{:message}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" hx-delete="/people/delete/{{:guid}}">Yes, delete it!</button>
<button type="button" class="btn btn-danger" data-bs-dismiss="modal" hx-target="#main" hx-delete="/people/delete/{{:guid}}">Yes, delete it!</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
</div>
</div>

View File

@ -1,14 +1,18 @@
</div>
<div class="row_fluid">
<div class="col-sm">
<div style="height: 100px"></div>
</div>
</div>
<div class="row">
<div class="col-sm bg-primary">
<span style="color: white">Powered by DMVCFramework</span>
</div>
<div class="col-sm bg-warning" style="text-align: right">
<span><a target="_blank" href="https://github.com/danieleteti/templatepro">Template Pro</a> project site</span>
<div class="col bg-primary bg-gradient">
<span id="footer" style="color: white">⭐ Powered by
<a target="_blank" href="https://github.com/danieleteti/delphimvcframework">DMVCFramework</a>
,
<a target="_blank" href="https://github.com/danieleteti/templatepro">Template Pro</a>
and
<a href="https://htmx.org/" target="_blank">HTMX</a>
</span>
</div>
</div>
</div>

View File

@ -1,19 +1,47 @@
<!DOCTYPE html>
<html>
<header>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
<style>
h1 a:hover {
text-decoration: none;
}
#footer a {
text-decoration: none;
}
/* unvisited link */
#footer a:link {
color: white;
}
/* visited link */
#footer a:visited {
color: white;
}
/* mouse over link */
#footer a:hover {
color: salmon;
}
/* selected link */
#footer a:active {
color: blue;
}
</style>
</header>
<body hx-boost="true" class="text-capitalize">
<div id="main" class="container">
<div id="container" class="container">
<div class="shadow-sm p-3 mb-5 bg-body-tertiary rounded">
<h1><a href="https://htmx.org/" target="_blank">HTMX</a> Sample</h1>
</div>
<h1 class="text-primary">✅CRUD Sample</h1>
</div>
<div id="main">

View File

@ -1 +0,0 @@
{{first_name}}, {{last_name}}

View File

@ -1,13 +1,13 @@
{{if(!ishtmx)}}
{{include("partials/header.html")}}
{{include("people_list_search.html")}}
{{endif}}
<div class="row" id="people_list">
{{include("people_list_search.html")}}
<div class="row" id="people_list" hx-target="#main">
<div class="col">
{{include("people_table.html")}}
</div>
</div>
{{if(!ishtmx)}}
{{include("people_list_bottom.html")}}
{{if(!ishtmx)}}
{{include("partials/footer.html")}}
{{endif}}

View File

@ -1,9 +1,10 @@
<div class="row padding mx-auto">
<div class="col-2 text-left">
<a href="/people/exports/csv" class="btn btn-dark" download="people.csv" target="_blank">Export as CSV</a>
<div class="col-2 text-start">
<a href="/people/exports/csv" class="btn btn-secondary" download="people.csv" target="_blank">Export as CSV</a>
</div>
<div class="offset-8 col-2 text-right">
<button class="btn btn-primary" hx-on:click="window.location.href = '/people/new'">Add New Person</button>
<div class="offset-8 col-2 text-end">
<!-- <button class="btn btn-primary" hx-on:click="window.location.href = '/people/new'">Add New Person</button> -->
<button class="btn btn-primary" hx-target="#main" hx-push-url="true" hx-get="/people/new">Add New Person</button>
</div>
</div>

View File

@ -1,8 +1,8 @@
<div class="row_fluid">
<div class="offset-sm-6 col-sm-6 text-right">
<form hx-get="/people" hx-target="#people_list">
<form hx-get="/people" hx-target="#main">
<div class="input-group mb-3">
<input name="q" type="text" class="form-control" placeholder="Contains..." value="{{:q}}">
<input id="search_text" name="q" type="text" class="form-control" placeholder="Contains..." value="{{:q}}">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="submit">Search</button>
</div>

View File

@ -17,10 +17,10 @@
{{loop(people) as person}}
<tr>
<td>{{:person.@@index}}</td>
<td>{{:person.FirstName}}</td>
<td>{{:person.LastName}}</td>
<td>{{:person.FirstName|capitalize}}</td>
<td>{{:person.LastName|capitalize}}</td>
<td>{{:person.Age}}</td>
<td class="text-right">{{include("delete_person_link.html")}} | {{include("view_person_link.html")}}</td>
<td class="text-end">{{include("delete_person_link.html")}} | {{include("view_person_link.html")}}</td>
</tr>
{{endloop}}
{{endif}}

View File

@ -1,85 +0,0 @@
<!DOCTYPE html>
<html>
<header>
<style>
body {
font-family: Consolas, 'Courier New';
}
blockquote {
font-style: italic;
color: #a0a0a0;
padding: 0.2em;
}
.section {
background-color: #3a3a3a;
color: white;
border-left: 0.5em red solid;
padding: 0.5em;
}
.box {
border: thin black solid;
margin: auto;
width: 80%;
padding: 2em;
}
</style>
</header>
<body>
<h1>Mustache Template Showcase <small><a href="/people">return to the app</a></small></h1>
<p>
This page is a showcase for all the mustache features usable from DMVCFramework Server Side Views using the default Mustache engine.
</p>
<div>
<h2 class="section">List of objects</h2>
<div>
{{^people}}
<div>No People Found</div>
{{/people}}
{{#people}}
<div>{{-index}}. {{first_name}} {{last_name}}</div>
{{/people}}
</div>
</div>
<div>
<h2 class="section">Handle empty list of objects</h2>
<div>
{{^people2}}
<div>No People Found</div>
{{/people2}}
{{#people2}}
<div>{{-index}}. {{first_name}} {{last_name}}</div>
{{/people2}}
</div>
</div>
<div>
<h2 class="section">Avoid HTML automatic escaping using {{=<% %>=}} {{{ content }}</h2>
<%={{ }}=%>
<div class="box">
{{#myobj}}
{{{rawhtml}}
{{/myobj}}
<br>
<blockquote >Check source code to know how to escape curly braces</blockquote >
</div>
</div>
<div>
<h2 class="section">Handling partials | <small>This partial is located in <code>partials/partial_person.mustache</code></small></h2>
<div>
<ul>
{{#people}}
<li>{{>partials/partial_person}}</li>
{{/people}}
</ul>
</div>
</div>
</body>
</html>

View File

@ -62,6 +62,8 @@ begin
// When MVCSerializeNulls = False empty nullables and nil are not serialized at all.
MVCSerializeNulls := True;
MVCUseTemplatesCache := False;
try
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := WebModuleClass;

View File

@ -29,20 +29,50 @@ interface
uses
System.Rtti;
function MyHelper1(const aValue: TValue; const aParameters: TArray<string>): string;
function MyHelper2(const aValue: TValue; const aParameters: TArray<string>): string;
procedure TemplateProContextConfigure;
implementation
function MyHelper1(const aValue: TValue; const aParameters: TArray<string>): string;
uses
TemplatePro, System.SysUtils;
function MyHelper1(const aValue: TValue; const aParameters: TArray<string>): TValue;
begin
Result := aValue.ToString + ' (I''m The MyHelper1)';
end;
function MyHelper2(const aValue: TValue; const aParameters: TArray<string>): string;
function MyHelper2(const aValue: TValue; const aParameters: TArray<string>): TValue;
begin
Result := aValue.ToString + ' (I''m The MyHelper2)';
end;
procedure TemplateProContextConfigure;
begin
TTProConfiguration.OnContextConfiguration := procedure(const CompiledTemplate: ITProCompiledTemplate)
begin
// These filters will be available to the TemplatePro views as if they were the standard ones
CompiledTemplate.AddFilter('MyHelper1', MyHelper1);
CompiledTemplate.AddFilter('MyHelper2', MyHelper2);
CompiledTemplate.OnGetValue :=
procedure(const DataSource, Members: string; var Value: TValue; var Handled: Boolean)
begin
if SameText(DataSource, 'ext1') then
begin
if Members.IsEmpty then
begin
Value := 'External Value Ext1'
end
else
begin
Value := 'Reading ext1.' + Members;
end;
Handled := True;
end;
end
end;
end;
end.

View File

@ -13,6 +13,7 @@ uses
{$ENDIF }
IdHTTPWebBrokerBridge,
TemplatePro,
MVCFramework.Commons,
MVCFramework.View.Renderers.TemplatePro,
Web.WebReq,
Web.WebBroker,
@ -48,17 +49,11 @@ end;
begin
ReportMemoryLeaksOnShutdown := True;
MVCUseTemplatesCache := True;
try
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := WebModuleClass;
// These filters will be available to the TemplatePro views as if they were the standard ones
TTProConfiguration.OnCustomFiltersRegistration := procedure(const TemplateProCompiledTemplate: ITProCompiledTemplate)
begin
TemplateProCompiledTemplate.AddFilter('MyHelper1', MyHelper1);
TemplateProCompiledTemplate.AddFilter('MyHelper2', MyHelper2);
end;
TemplateProContextConfigure;
RunServer(8080);
except
on E: Exception do

View File

@ -129,5 +129,18 @@ This page is a showcase for all the TemplatePro features usable from DMVCFramewo
</p>
</div>
<div>
<h2 class="section">Using OnGetValue event</h2>
<p>
<p>{{:ext1}}</p>
<p>{{:ext1.field1}}</p>
<p>{{:ext1.field1.value}}</p>
</p>
</div>
</body>
</html>

View File

@ -639,8 +639,14 @@ var
/// When MVCSerializeNulls = False empty nullables and nil are not serialized at all.
/// </summary>
MVCSerializeNulls: Boolean = True;
/// <summary>
/// If "true" server side views templates are cached on disk for better performance.
/// </summary>
MVCUseTemplatesCache: Boolean = True;
{ GLOBAL CONFIG VARS // END}
function AppPath: string;
function IsReservedOrPrivateIP(const AIP: string): Boolean; inline;
function IP2Long(const AIP: string): UInt32; inline;

View File

@ -51,12 +51,12 @@ uses
{$WARNINGS OFF}
function GetDataSetOrObjectListCount(const aValue: TValue; const aParameters: TArray<string>): string;
function GetDataSetOrObjectListCount(const aValue: TValue; const aParameters: TArray<string>): TValue;
begin
// todo
end;
function DumpAsJSONString(const aValue: TValue; const aParameters: TArray<string>): string;
function DumpAsJSONString(const aValue: TValue; const aParameters: TArray<string>): TValue;
var
lWrappedList: IMVCList;
begin
@ -93,19 +93,23 @@ var
begin
lUseCompiledVersion := False;
lViewFileName := GetRealFileName(ViewName);
lCacheDir := TPath.Combine(TPath.GetDirectoryName(lViewFileName), '__cache__');
TDirectory.CreateDirectory(lCacheDir);
lCompiledViewFileName := TPath.Combine(lCacheDir, TPath.ChangeExtension(TPath.GetFileName(lViewFileName), '.tpcu'));
if not FileAge(lViewFileName, lActualFileTimeStamp) then
if MVCUseTemplatesCache then
begin
raise EMVCFrameworkViewException.CreateFmt('View [%s] not found',
[ViewName]);
end;
lCacheDir := TPath.Combine(TPath.GetDirectoryName(lViewFileName), '__cache__');
TDirectory.CreateDirectory(lCacheDir);
lCompiledViewFileName := TPath.Combine(lCacheDir, TPath.ChangeExtension(TPath.GetFileName(lViewFileName), '.' + TEMPLATEPRO_VERSION + '.tpcu'));
if FileAge(lCompiledViewFileName, lActualCompiledFileTimeStamp) then
begin
lUseCompiledVersion := lActualFileTimeStamp < lActualCompiledFileTimeStamp;
if not FileAge(lViewFileName, lActualFileTimeStamp) then
begin
raise EMVCFrameworkViewException.CreateFmt('View [%s] not found',
[ViewName]);
end;
if FileAge(lCompiledViewFileName, lActualCompiledFileTimeStamp) then
begin
lUseCompiledVersion := lActualFileTimeStamp < lActualCompiledFileTimeStamp;
end;
end;
if lUseCompiledVersion then
@ -118,7 +122,10 @@ begin
try
lViewTemplate := TFile.ReadAllText(lViewFileName);
lCompiledTemplate := lTP.Compile(lViewTemplate, lViewFileName);
lCompiledTemplate.SaveToFile(lCompiledViewFileName);
if MVCUseTemplatesCache then
begin
lCompiledTemplate.SaveToFile(lCompiledViewFileName);
end;
finally
lTP.Free;
end;

View File

@ -4623,7 +4623,7 @@ end;
procedure TMVCController.SetViewData(const aModelName: string; const Value: TValue);
begin
GetViewModel.Add(aModelName, Value);
GetViewModel.AddOrSetValue(aModelName, Value);
end;
procedure TMVCRenderer.Render(

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
const
DMVCFRAMEWORK_VERSION = '3.4.2-magnesium-rc2';
DMVCFRAMEWORK_VERSION = '3.4.2-magnesium-rc3';