mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 15:55:54 +01:00
New sample: HTMX_mustache, fix for some unit test, workaround for IdCustomHTTP strange behaviour in case of empty response and HTTP 200 OK.
This commit is contained in:
parent
4a931c13ad
commit
3d910bdfed
@ -373,6 +373,8 @@ resourcestring
|
||||
' Config[TMVCConfigKey.DefaultViewFileExtension] := dotEnv.Env(''dmvc.default.view_file_extension'', ''html'');' + sLineBreak +
|
||||
' //view path' + sLineBreak +
|
||||
' Config[TMVCConfigKey.ViewPath] := dotEnv.Env(''dmvc.view_path'', ''templates'');' + sLineBreak +
|
||||
' //use cache for server side views (use "false" in debug and "true" in production for faster performances' + sLineBreak +
|
||||
' Config[TMVCConfigKey.ViewCache] := dotEnv.Env(''dmvc.view_cache'', ''false'');' + sLineBreak +
|
||||
' //Max Record Count for automatic Entities CRUD' + sLineBreak +
|
||||
' Config[TMVCConfigKey.MaxEntitiesRecordCount] := dotEnv.Env(''dmvc.max_entities_record_count'', IntToStr(TMVCConstants.MAX_RECORD_COUNT));' + sLineBreak +
|
||||
' //Enable Server Signature in response' + sLineBreak +
|
||||
|
307
samples/htmx_mustache/DAL.pas
Normal file
307
samples/htmx_mustache/DAL.pas
Normal file
@ -0,0 +1,307 @@
|
||||
unit DAL;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.JSON,
|
||||
MVCFramework.SystemJSONUtils,
|
||||
System.Generics.Collections,
|
||||
MVCFramework.Serializer.Commons;
|
||||
|
||||
type
|
||||
|
||||
[MVCNameCase(ncLowerCase)]
|
||||
TPerson = class
|
||||
private
|
||||
FFirstName: string;
|
||||
FLastName: string;
|
||||
FAge: Integer;
|
||||
FItems: string;
|
||||
FGUID: string;
|
||||
procedure SetFirstName(const Value: string);
|
||||
procedure SetLastName(const Value: string);
|
||||
procedure SetAge(const Value: Integer);
|
||||
procedure SetGUID(const Value: string);
|
||||
procedure SetItems(const Value: string);
|
||||
public
|
||||
[MVCNameAs('first_name')]
|
||||
property FirstName: string read FFirstName write SetFirstName;
|
||||
[MVCNameAs('last_name')]
|
||||
property LastName: string read FLastName write SetLastName;
|
||||
property Age: Integer read FAge write SetAge;
|
||||
property Items: string read FItems write SetItems;
|
||||
property GUID: string read FGUID write SetGUID;
|
||||
end;
|
||||
|
||||
TPeople = class(TObjectList<TPerson>)
|
||||
end;
|
||||
|
||||
{$M+}
|
||||
TMyObj = class
|
||||
private
|
||||
FRawHTML: String;
|
||||
procedure SetRawHTML(const Value: String);
|
||||
published
|
||||
property RawHTML: String read FRawHTML write SetRawHTML;
|
||||
end;
|
||||
{$M-}
|
||||
|
||||
TDevice = class
|
||||
private
|
||||
fDeviceName: string;
|
||||
fSelected: Boolean;
|
||||
public
|
||||
property DeviceName: string read fDeviceName write fDeviceName;
|
||||
property Selected: Boolean read fSelected write fSelected;
|
||||
constructor Create(aDeviceName: string; aSelected: Boolean);
|
||||
end;
|
||||
|
||||
TDeviceList = class(TObjectList<TDevice>)
|
||||
public
|
||||
function Contains(const aDeviceName: string): Boolean;
|
||||
function IndexOf(const aDeviceName: string): Integer;
|
||||
end;
|
||||
|
||||
IPeopleDAL = interface
|
||||
['{3E534A3E-EAEB-44ED-B74E-EFBBAAAE11B4}']
|
||||
function GetPeople(const SearchText: String = ''): TPeople;
|
||||
procedure AddPerson(FirstName, LastName: string; Age: Integer;
|
||||
Items: TArray<string>);
|
||||
procedure DeleteByGUID(GUID: string);
|
||||
function GetPersonByGUID(GUID: string): TPerson;
|
||||
function GetDevicesList: TDeviceList;
|
||||
end;
|
||||
|
||||
TPeopleDAL = class(TInterfacedObject, IPeopleDAL)
|
||||
private const
|
||||
DATAFILE: string = 'people.data';
|
||||
public
|
||||
function GetPeople(const SearchText: String = ''): TPeople;
|
||||
procedure AddPerson(FirstName, LastName: string; Age: Integer;
|
||||
Items: TArray<string>);
|
||||
procedure DeleteByGUID(GUID: string);
|
||||
function GetPersonByGUID(GUID: string): TPerson;
|
||||
function GetDevicesList: TDeviceList;
|
||||
end;
|
||||
|
||||
TServicesFactory = class sealed
|
||||
class function GetPeopleDAL: IPeopleDAL;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.SyncObjs,
|
||||
System.IOUtils,
|
||||
MVCFramework.Serializer.Defaults,
|
||||
System.SysUtils;
|
||||
|
||||
var
|
||||
// Hey! The storage is a simple json file, so some synchronization is needed
|
||||
_CS: TCriticalSection = nil;
|
||||
|
||||
{ TSimpleDAL }
|
||||
|
||||
procedure TPeopleDAL.AddPerson(FirstName, LastName: string; Age: Integer;
|
||||
Items: TArray<string>);
|
||||
var
|
||||
lPeople: TPeople;
|
||||
lPerson: TPerson;
|
||||
begin
|
||||
_CS.Enter;
|
||||
try
|
||||
lPeople := GetPeople();
|
||||
try
|
||||
lPerson := TPerson.Create;
|
||||
lPeople.Add(lPerson);
|
||||
lPerson.FirstName := FirstName;
|
||||
lPerson.LastName := LastName;
|
||||
lPerson.Age := Age;
|
||||
lPerson.Items := string.Join(',', Items);
|
||||
lPerson.GUID := TGuid.NewGuid.ToString.Replace('{', '').Replace('}', '')
|
||||
.Replace('-', '');
|
||||
TFile.WriteAllText(DATAFILE, GetDefaultSerializer.SerializeCollection
|
||||
(lPeople));
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
finally
|
||||
_CS.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TServicesFactory.GetPeopleDAL: IPeopleDAL;
|
||||
begin
|
||||
Result := TPeopleDAL.Create;
|
||||
end;
|
||||
|
||||
procedure TPeopleDAL.DeleteByGUID(GUID: string);
|
||||
var
|
||||
LJPeople: TPeople;
|
||||
I: Integer;
|
||||
begin
|
||||
_CS.Enter;
|
||||
try
|
||||
LJPeople := GetPeople;
|
||||
try
|
||||
for I := 0 to LJPeople.Count - 1 do
|
||||
begin
|
||||
if LJPeople[I].GUID = GUID then
|
||||
begin
|
||||
LJPeople.Delete(I);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
TFile.WriteAllText(DATAFILE, GetDefaultSerializer.SerializeCollection
|
||||
(LJPeople));
|
||||
finally
|
||||
LJPeople.Free;
|
||||
end;
|
||||
finally
|
||||
_CS.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPeopleDAL.GetDevicesList: TDeviceList;
|
||||
begin
|
||||
Result := TDeviceList.Create(true);
|
||||
Result.Add(TDevice.Create('smartphone', false));
|
||||
Result.Add(TDevice.Create('dumbphone', false));
|
||||
Result.Add(TDevice.Create('laptop', false));
|
||||
Result.Add(TDevice.Create('desktop', false));
|
||||
end;
|
||||
|
||||
function TPeopleDAL.GetPeople(const SearchText: String): TPeople;
|
||||
var
|
||||
LData: string;
|
||||
lSearch: String;
|
||||
begin
|
||||
lSearch := SearchText.ToLower;
|
||||
_CS.Enter;
|
||||
try
|
||||
Result := TPeople.Create;
|
||||
if TFile.Exists(DATAFILE) then
|
||||
LData := TFile.ReadAllText(DATAFILE).Trim;
|
||||
if not LData.IsEmpty then
|
||||
begin
|
||||
GetDefaultSerializer.DeserializeCollection(LData, Result, TPerson);
|
||||
end;
|
||||
if not SearchText.IsEmpty then
|
||||
begin
|
||||
var lToDelete := TPeople.Create(False);
|
||||
try
|
||||
for var I := 0 to Result.Count-1 do
|
||||
begin
|
||||
if not (
|
||||
Result[i].FirstName.ToLower.Contains(lSearch) or
|
||||
Result[i].LastName.ToLower.Contains(lSearch)) then
|
||||
begin
|
||||
lToDelete.Add(Result[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
for var I := 0 to lToDelete.Count-1 do
|
||||
begin
|
||||
Result.Remove(lToDelete[I]);
|
||||
end;
|
||||
finally
|
||||
lToDelete.Free;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
_CS.Leave;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPeopleDAL.GetPersonByGUID(GUID: string): TPerson;
|
||||
var
|
||||
lPeople: TPeople;
|
||||
lPerson: TPerson;
|
||||
begin
|
||||
Result := nil;
|
||||
lPeople := GetPeople;
|
||||
try
|
||||
for lPerson in lPeople do
|
||||
begin
|
||||
if lPerson.GUID = GUID then
|
||||
begin
|
||||
Result := lPeople.Extract(lPerson);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TPerson }
|
||||
|
||||
procedure TPerson.SetAge(const Value: Integer);
|
||||
begin
|
||||
FAge := Value;
|
||||
end;
|
||||
|
||||
procedure TPerson.SetFirstName(const Value: string);
|
||||
begin
|
||||
FFirstName := Value;
|
||||
end;
|
||||
|
||||
procedure TPerson.SetGUID(const Value: string);
|
||||
begin
|
||||
FGUID := Value;
|
||||
end;
|
||||
|
||||
procedure TPerson.SetItems(const Value: string);
|
||||
begin
|
||||
FItems := Value;
|
||||
end;
|
||||
|
||||
procedure TPerson.SetLastName(const Value: string);
|
||||
begin
|
||||
FLastName := Value;
|
||||
end;
|
||||
|
||||
{ TDevice }
|
||||
|
||||
constructor TDevice.Create(aDeviceName: string; aSelected: Boolean);
|
||||
begin
|
||||
inherited Create;
|
||||
fDeviceName := aDeviceName;
|
||||
fSelected := aSelected;
|
||||
end;
|
||||
|
||||
{ TDeviceList }
|
||||
|
||||
function TDeviceList.Contains(const aDeviceName: string): Boolean;
|
||||
begin
|
||||
Result := IndexOf(aDeviceName) > -1;
|
||||
end;
|
||||
|
||||
function TDeviceList.IndexOf(const aDeviceName: string): Integer;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Result := -1;
|
||||
for I := 0 to Self.Count - 1 do
|
||||
begin
|
||||
if SameText(Self[I].DeviceName, aDeviceName) then
|
||||
Exit(I);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TRawObj }
|
||||
|
||||
procedure TMyObj.SetRawHTML(const Value: String);
|
||||
begin
|
||||
FRawHTML := Value;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
_CS := TCriticalSection.Create;
|
||||
|
||||
finalization
|
||||
|
||||
_CS.Free;
|
||||
|
||||
end.
|
12
samples/htmx_mustache/WebModuleU.dfm
Normal file
12
samples/htmx_mustache/WebModuleU.dfm
Normal file
@ -0,0 +1,12 @@
|
||||
object WebModule1: TWebModule1
|
||||
OnCreate = WebModuleCreate
|
||||
OnDestroy = WebModuleDestroy
|
||||
Actions = <
|
||||
item
|
||||
Default = True
|
||||
Name = 'DefaultHandler'
|
||||
PathInfo = '/'
|
||||
end>
|
||||
Height = 230
|
||||
Width = 415
|
||||
end
|
77
samples/htmx_mustache/WebModuleU.pas
Normal file
77
samples/htmx_mustache/WebModuleU.pas
Normal file
@ -0,0 +1,77 @@
|
||||
unit WebModuleU;
|
||||
|
||||
interface
|
||||
|
||||
uses System.SysUtils, System.Classes, Web.HTTPApp, MVCFramework;
|
||||
|
||||
type
|
||||
TWebModule1 = class(TWebModule)
|
||||
procedure WebModuleCreate(Sender: TObject);
|
||||
procedure WebModuleDestroy(Sender: TObject);
|
||||
private
|
||||
FMVCEngine: TMVCEngine;
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
WebModuleClass: TComponentClass = TWebModule1;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
MVCFramework.View.Renderers.Mustache,
|
||||
WebSiteControllerU,
|
||||
System.IOUtils,
|
||||
MVCFramework.Commons,
|
||||
MVCFramework.Middleware.Redirect,
|
||||
MVCFramework.Middleware.StaticFiles;
|
||||
|
||||
{ %CLASSGROUP 'Vcl.Controls.TControl' }
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
procedure TWebModule1.WebModuleCreate(Sender: TObject);
|
||||
begin
|
||||
FMVCEngine := TMVCEngine.Create(Self,
|
||||
procedure(Config: TMVCConfig)
|
||||
begin
|
||||
Config.dotEnv := dotEnv;
|
||||
// session timeout (0 means session cookie)
|
||||
Config[TMVCConfigKey.SessionTimeout] := dotEnv.Env('dmvc.session_timeout', '0');
|
||||
//default content-type
|
||||
Config[TMVCConfigKey.DefaultContentType] := dotEnv.Env('dmvc.default.content_type', TMVCMediaType.TEXT_HTML);
|
||||
//default content charset
|
||||
Config[TMVCConfigKey.DefaultContentCharset] := dotEnv.Env('dmvc.default.content_charset', TMVCConstants.DEFAULT_CONTENT_CHARSET);
|
||||
//unhandled actions are permitted?
|
||||
Config[TMVCConfigKey.AllowUnhandledAction] := dotEnv.Env('dmvc.allow_unhandled_actions', 'false');
|
||||
//enables or not system controllers loading (available only from localhost requests)
|
||||
Config[TMVCConfigKey.LoadSystemControllers] := dotEnv.Env('dmvc.load_system_controllers', 'true');
|
||||
//default view file extension
|
||||
Config[TMVCConfigKey.DefaultViewFileExtension] := dotEnv.Env('dmvc.default.view_file_extension', 'mustache');
|
||||
//view path
|
||||
Config[TMVCConfigKey.ViewPath] := dotEnv.Env('dmvc.view_path', 'templates');
|
||||
//use cache for server side views (use "false" in debug and "true" in production for faster performances
|
||||
Config[TMVCConfigKey.ViewCache] := dotEnv.Env('dmvc.view_cache', 'false');
|
||||
//Max Record Count for automatic Entities CRUD
|
||||
Config[TMVCConfigKey.MaxEntitiesRecordCount] := dotEnv.Env('dmvc.max_entities_record_count', IntToStr(TMVCConstants.MAX_RECORD_COUNT));
|
||||
//Enable Server Signature in response
|
||||
Config[TMVCConfigKey.ExposeServerSignature] := dotEnv.Env('dmvc.expose_server_signature', 'false');
|
||||
//Enable X-Powered-By Header in response
|
||||
Config[TMVCConfigKey.ExposeXPoweredBy] := dotEnv.Env('dmvc.expose_x_powered_by', 'true');
|
||||
// Max request size in bytes
|
||||
Config[TMVCConfigKey.MaxRequestSize] := dotEnv.Env('dmvc.max_request_size', IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE));
|
||||
end)
|
||||
.AddController(TWebSiteController)
|
||||
.AddMiddleware(TMVCRedirectMiddleware.Create(['/'],'/people'))
|
||||
.SetViewEngine(TMVCMustacheViewEngine)
|
||||
end;
|
||||
|
||||
procedure TWebModule1.WebModuleDestroy(Sender: TObject);
|
||||
begin
|
||||
FMVCEngine.Free;
|
||||
end;
|
||||
|
||||
end.
|
245
samples/htmx_mustache/WebSiteControllerU.pas
Normal file
245
samples/htmx_mustache/WebSiteControllerU.pas
Normal file
@ -0,0 +1,245 @@
|
||||
unit WebSiteControllerU;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
MVCFramework, System.Diagnostics, JsonDataObjects, MVCFramework.Commons, MVCFramework.HTMX;
|
||||
|
||||
type
|
||||
|
||||
[MVCPath('/people')]
|
||||
TWebSiteController = class(TMVCController)
|
||||
protected
|
||||
function GeneratePeopleListAsCSV: String;
|
||||
public
|
||||
[MVCPath]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
function PeopleList: String;
|
||||
|
||||
[MVCPath('/search')]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
function PeopleSearch(const [MVCFromQueryString('q', '')] SearchText: String): String;
|
||||
|
||||
[MVCPath('/exports/csv')]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
function ExportPeopleListAsCSV_API: String;
|
||||
|
||||
[MVCPath]
|
||||
[MVCHTTPMethods([httpPOST])]
|
||||
[MVCConsumes(TMVCMediaType.APPLICATION_FORM_URLENCODED)]
|
||||
procedure SavePerson;
|
||||
|
||||
[MVCPath('/delete/($guid)')]
|
||||
[MVCHTTPMethods([httpDELETE])]
|
||||
procedure DeletePerson(const guid: string);
|
||||
|
||||
[MVCPath('/new')]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
||||
procedure NewPerson;
|
||||
|
||||
[MVCPath('/edit/($guid)')]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
||||
function EditPerson(guid: string): String;
|
||||
|
||||
[MVCPath]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
||||
procedure Index;
|
||||
|
||||
[MVCPath('/mustacheshowcase')]
|
||||
[MVCHTTPMethods([httpGET])]
|
||||
[MVCProduces(TMVCMediaType.TEXT_HTML)]
|
||||
procedure MustacheTemplateShowCase;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TWebSiteController }
|
||||
|
||||
uses DAL, System.SysUtils, Web.HTTPApp;
|
||||
|
||||
procedure TWebSiteController.DeletePerson(const guid: string);
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
LDAL.DeleteByGUID(GUID);
|
||||
RenderStatusMessage(HTTP_STATUS.OK);
|
||||
end;
|
||||
|
||||
function TWebSiteController.EditPerson(guid: string): String;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lPerson: TPerson;
|
||||
lDevices: TDeviceList;
|
||||
lItem: TDevice;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
lPerson := LDAL.GetPersonByGUID(guid);
|
||||
try
|
||||
lDevices := LDAL.GetDevicesList;
|
||||
try
|
||||
ViewData['person'] := lPerson;
|
||||
for lItem in lDevices do
|
||||
begin
|
||||
lItem.Selected := lPerson.Items.Contains(lItem.DeviceName);
|
||||
end;
|
||||
ViewData['deviceslist'] := lDevices;
|
||||
Result := GetRenderedView(['header', 'editperson', 'footer']);
|
||||
finally
|
||||
lDevices.Free;
|
||||
end;
|
||||
finally
|
||||
lPerson.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWebSiteController.ExportPeopleListAsCSV_API: String;
|
||||
begin
|
||||
ContentType := TMVCMediaType.TEXT_CSV;
|
||||
Context.Response.CustomHeaders.Values['Content-Disposition'] := 'attachment; filename=people.csv';
|
||||
Result := GeneratePeopleListAsCSV;
|
||||
end;
|
||||
|
||||
function TWebSiteController.GeneratePeopleListAsCSV: String;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lPeople: TPeople;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
lPeople := LDAL.GetPeople;
|
||||
try
|
||||
ViewData['people'] := lPeople;
|
||||
Result := GetRenderedView(['people_header.csv', 'people_list.csv']);
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWebSiteController.Index;
|
||||
begin
|
||||
Redirect('/people');
|
||||
end;
|
||||
|
||||
procedure TWebSiteController.MustacheTemplateShowCase;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lPeople, lPeople2: TPeople;
|
||||
lMyObj: TMyObj;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
lPeople := LDAL.GetPeople;
|
||||
try
|
||||
lPeople2 := TPeople.Create;
|
||||
try
|
||||
lMyObj := TMyObj.Create;
|
||||
try
|
||||
lMyObj.RawHTML := '<h1>This is</h1>Raw<br><span>HTML</span>';
|
||||
ViewData['people'] := lPeople;
|
||||
ViewData['people2'] := lPeople2;
|
||||
ViewData['myobj'] := lMyObj;
|
||||
LoadView(['showcase']);
|
||||
RenderResponseStream;
|
||||
finally
|
||||
lMyObj.Free;
|
||||
end;
|
||||
finally
|
||||
lPeople2.Free;
|
||||
end;
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWebSiteController.NewPerson;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lDevices: TDeviceList;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
lDevices := LDAL.GetDevicesList;
|
||||
try
|
||||
ViewData['deviceslist'] := lDevices;
|
||||
LoadView(['header', 'editperson', 'footer']);
|
||||
RenderResponseStream;
|
||||
finally
|
||||
lDevices.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWebSiteController.PeopleList: String;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lPeople: TPeople;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
lPeople := LDAL.GetPeople;
|
||||
try
|
||||
ViewData['people'] := lPeople;
|
||||
Result := GetRenderedView(['header', 'people_list_search', 'people_list', 'people_list_bottom', 'footer']);
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TWebSiteController.PeopleSearch(const SearchText: String): String;
|
||||
var
|
||||
LDAL: IPeopleDAL;
|
||||
lPeople: TPeople;
|
||||
begin
|
||||
LDAL := TServicesFactory.GetPeopleDAL;
|
||||
|
||||
lPeople := LDAL.GetPeople(SearchText);
|
||||
try
|
||||
ViewData['people'] := lPeople;
|
||||
if Context.Request.IsHTMX then
|
||||
begin
|
||||
Result := GetRenderedView(['people_list']);
|
||||
if SearchText.IsEmpty then
|
||||
Context.Response.SetPushUrl('/people/search')
|
||||
else
|
||||
Context.Response.SetPushUrl('/people/search?q=' + SearchText);
|
||||
end
|
||||
else
|
||||
begin
|
||||
var lJSON := TJSONObject.Create;
|
||||
try
|
||||
lJSON.S['q'] := SearchText;
|
||||
Result := GetRenderedView(['header', 'people_list_search', 'people_list', 'people_list_bottom', 'footer'], lJSON);
|
||||
finally
|
||||
lJSON.Free;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
lPeople.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWebSiteController.SavePerson;
|
||||
var
|
||||
LFirstName: string;
|
||||
LLastName: string;
|
||||
LAge: string;
|
||||
LPeopleDAL: IPeopleDAL;
|
||||
lDevices: TArray<string>;
|
||||
begin
|
||||
LFirstName := Context.Request.Params['first_name'].Trim;
|
||||
LLastName := Context.Request.Params['last_name'].Trim;
|
||||
LAge := Context.Request.Params['age'];
|
||||
lDevices := Context.Request.ParamsMulti['items'];
|
||||
|
||||
if LFirstName.IsEmpty or LLastName.IsEmpty or LAge.IsEmpty then
|
||||
begin
|
||||
{ TODO -oDaniele -cGeneral : Show how to properly render an exception }
|
||||
raise EMVCException.Create('Invalid data', 'First name, last name and age are not optional', 0);
|
||||
end;
|
||||
|
||||
LPeopleDAL := TServicesFactory.GetPeopleDAL;
|
||||
LPeopleDAL.AddPerson(LFirstName, LLastName, LAge.ToInteger(), lDevices);
|
||||
Context.Response.SetRedirect('/people');
|
||||
end;
|
||||
|
||||
end.
|
@ -0,0 +1 @@
|
||||
<a hx-delete="/people/delete/{{guid}}" hx-confirm="Are you sure to delete {{first_name}} {{last_name}} ?" href="" hx-swap="delete" hx-target="closest tr">Delete</a>
|
81
samples/htmx_mustache/bin/templates/editperson.mustache
Normal file
81
samples/htmx_mustache/bin/templates/editperson.mustache
Normal file
@ -0,0 +1,81 @@
|
||||
<script>
|
||||
function doDelete(id) {
|
||||
if (confirm('Are you sure?')) {
|
||||
let form = document.getElementById("myForm");
|
||||
form.action = "/deleteperson";
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<form class="form form-horizontal" id="myForm" name="myForm" hx-post="/people">
|
||||
<input type="hidden" value="{{person.guid}}" name="guid">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{^person}}
|
||||
<h3>New Person</h3>
|
||||
{{/person}} {{#person}}
|
||||
<h3>Edit Person</h3>
|
||||
{{/person}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label for="first_name" class="control-label">First name</label>
|
||||
<input type="text" value="{{person.first_name}}" class="form-control" id="first_name" placeholder="First name" name="first_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label for="last_name" class="control-label">Last name</label>
|
||||
<input type="text" value="{{person.last_name}}" class="form-control" id="last_name" placeholder="Last name" name="last_name">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label for="age" class="control-label">Age</label>
|
||||
<input type="number" value="{{person.age}}" class="form-control" id="age" placeholder="Age" name="age">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="form-group">
|
||||
<label for="items" class="col-sm-10 control-label">Devices</label>
|
||||
<select name="items" multiple class="form-control">
|
||||
{{#deviceslist}}
|
||||
<option value="{{devicename}}" {{#selected}}selected{{/selected}}>{{devicename}}</option>
|
||||
{{/deviceslist}}
|
||||
</select>
|
||||
<span style="font-size: 80%">(Ctrl+Click to select multiple devices)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-default btn-block" onclick="history.back()">Return to the list</button>
|
||||
</div>
|
||||
<div class="offset-5">
|
||||
</div>
|
||||
<div class="col">
|
||||
{{#person}}
|
||||
<button
|
||||
type="button"
|
||||
hx-confirm="Are you sure you wish to delete user?"
|
||||
hx-delete="/people/delete/{{#person}}{{guid}}{{/person}}"
|
||||
class="btn btn-warning btn-block">
|
||||
Delete
|
||||
</button>
|
||||
{{/person}}
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="submit" class="btn btn-primary btn-block">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
24
samples/htmx_mustache/bin/templates/footer.mustache
Normal file
24
samples/htmx_mustache/bin/templates/footer.mustache
Normal file
@ -0,0 +1,24 @@
|
||||
<div class="row_fluid">
|
||||
<div class="col-sm">
|
||||
<div style="height: 100px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row_fluid">
|
||||
<div class="col-sm">
|
||||
<span>N.B. All these views are UTF-8 encoded with BOM</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm bg-primary">
|
||||
<span>Powered by DMVCFramework</span>
|
||||
</div>
|
||||
<div class="col-sm bg-warning">
|
||||
<span>Server Side Views <a href="/people/mustacheshowcase">showcase</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
17
samples/htmx_mustache/bin/templates/header.mustache
Normal file
17
samples/htmx_mustache/bin/templates/header.mustache
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<header>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
<script src="https://unpkg.com/htmx.org@1.9.6" integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni" crossorigin="anonymous"></script>
|
||||
<style>
|
||||
body {
|
||||
padding: 20px 50px 20px 50px;
|
||||
}
|
||||
</style>
|
||||
</header>
|
||||
|
||||
<body>
|
||||
<div id="main" class="container">
|
||||
<div class="shadow-sm p-3 mb-5 bg-body-tertiary rounded">
|
||||
<h1>HTMX Sample <small>DMVCFramework</small></h1>
|
||||
</div>
|
@ -0,0 +1 @@
|
||||
{{first_name}}, {{last_name}}
|
@ -0,0 +1 @@
|
||||
guid;first_name;last_name;age
|
@ -0,0 +1,2 @@
|
||||
{{#people}}{{guid}};"{{first_name}}";"{{last_name}}";{{age}}
|
||||
{{/people}}
|
5
samples/htmx_mustache/bin/templates/people_list.mustache
Normal file
5
samples/htmx_mustache/bin/templates/people_list.mustache
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="row_fluid" id="people_list">
|
||||
<div class="col-sm-12">
|
||||
{{>people_table}}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,8 @@
|
||||
<div class="row">
|
||||
<div class="offset-7 col-2">
|
||||
<a href="/people/exports/csv" download="people.csv" target="_blank">Export as CSV</a>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<a hx-boost="true" href="/people/new">Add New Person</a>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,13 @@
|
||||
<div class="row_fluid">
|
||||
<div class="offset-sm-6 col-sm-6 text-right">
|
||||
<form hx-get="/people/search" hx-target="#people_list">
|
||||
<div class="input-group mb-3">
|
||||
<input 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>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
26
samples/htmx_mustache/bin/templates/people_table.mustache
Normal file
26
samples/htmx_mustache/bin/templates/people_table.mustache
Normal file
@ -0,0 +1,26 @@
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">First name</th>
|
||||
<th scope="col">Last name</th>
|
||||
<th scope="col">Age</th>
|
||||
<th scope="col"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{^people}}
|
||||
<tr>
|
||||
<td class="text-center" colspan="5"><<No People Found>></td>
|
||||
</tr>
|
||||
{{/people}} {{#people}}
|
||||
<tr>
|
||||
<td>{{-index}}</td>
|
||||
<td>{{first_name}}</td>
|
||||
<td>{{last_name}}</td>
|
||||
<td>{{age}}</td>
|
||||
<td class="text-right">{{>delete_person_link}} | {{>view_person_link}}</td>
|
||||
</tr>
|
||||
{{/people}}
|
||||
</tbody>
|
||||
</table>
|
85
samples/htmx_mustache/bin/templates/showcase.mustache
Normal file
85
samples/htmx_mustache/bin/templates/showcase.mustache
Normal file
@ -0,0 +1,85 @@
|
||||
<!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>
|
@ -0,0 +1 @@
|
||||
<a href="/people/edit/{{guid}}">View</a>
|
86
samples/htmx_mustache/htmx_mustache.dpr
Normal file
86
samples/htmx_mustache/htmx_mustache.dpr
Normal file
@ -0,0 +1,86 @@
|
||||
program htmx_mustache;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
MVCFramework,
|
||||
MVCFramework.Signal,
|
||||
MVCFramework.Logger,
|
||||
{$IFDEF MSWINDOWS}
|
||||
Winapi.ShellAPI,
|
||||
Winapi.Windows,
|
||||
{$ENDIF }
|
||||
IdHTTPWebBrokerBridge,
|
||||
Web.WebReq,
|
||||
Web.WebBroker,
|
||||
WebModuleU in 'WebModuleU.pas' {WebModule1: TWebModule},
|
||||
WebSiteControllerU in 'WebSiteControllerU.pas',
|
||||
DAL in 'DAL.pas',
|
||||
MyDataModuleU in '..\renders\MyDataModuleU.pas' {MyDataModule: TDataModule},
|
||||
MVCFramework.HTMX in '..\htmx\MVCFramework.HTMX.pas', MVCFramework.Commons,
|
||||
MVCFramework.DotEnv;
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
||||
procedure RunServer(APort: Integer);
|
||||
var
|
||||
LServer: TIdHTTPWebBrokerBridge;
|
||||
begin
|
||||
ReportMemoryLeaksOnShutdown := True;
|
||||
Writeln(Format('Starting HTTP Server on port %d', [APort]));
|
||||
LServer := TIdHTTPWebBrokerBridge.Create(nil);
|
||||
try
|
||||
LServer.DefaultPort := APort;
|
||||
LServer.Active := True;
|
||||
{$IFDEF MSWINDOWS}
|
||||
ShellExecute(0, 'open', 'http://localhost:8080', nil, nil, SW_SHOW);
|
||||
{$ENDIF}
|
||||
Write('Ctrl+C to stop the server');
|
||||
WaitForTerminationSignal;
|
||||
EnterInShutdownState;
|
||||
LServer.Active := False;
|
||||
finally
|
||||
LServer.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
{ Enable ReportMemoryLeaksOnShutdown during debug }
|
||||
// ReportMemoryLeaksOnShutdown := True;
|
||||
IsMultiThread := True;
|
||||
|
||||
// DMVCFramework Specific Configuration
|
||||
// When MVCSerializeNulls = True empty nullables and nil are serialized as json null.
|
||||
// When MVCSerializeNulls = False empty nullables and nil are not serialized at all.
|
||||
MVCSerializeNulls := True;
|
||||
|
||||
try
|
||||
if WebRequestHandler <> nil then
|
||||
WebRequestHandler.WebModuleClass := WebModuleClass;
|
||||
|
||||
dotEnvConfigure(
|
||||
function: IMVCDotEnv
|
||||
begin
|
||||
Result := NewDotEnv
|
||||
.WithStrategy(TMVCDotEnvPriority.FileThenEnv)
|
||||
//if available, by default, loads default environment (.env)
|
||||
.UseProfile('test') //if available loads the test environment (.env.test)
|
||||
.UseProfile('prod') //if available loads the prod environment (.env.prod)
|
||||
.UseLogger(procedure(LogItem: String)
|
||||
begin
|
||||
LogW('dotEnv: ' + LogItem);
|
||||
end)
|
||||
.Build(); //uses the executable folder to look for .env* files
|
||||
end);
|
||||
|
||||
WebRequestHandlerProc.MaxConnections := dotEnv.Env('dmvc.handler.max_connections', 1024);
|
||||
RunServer(dotEnv.Env('dmvc.server.port', 8080));
|
||||
except
|
||||
on E: Exception do
|
||||
Writeln(E.ClassName, ': ', E.Message);
|
||||
end;
|
||||
|
||||
end.
|
869
samples/htmx_mustache/htmx_mustache.dproj
Normal file
869
samples/htmx_mustache/htmx_mustache.dproj
Normal file
@ -0,0 +1,869 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{563921D8-AB80-4E14-AD4E-36870C7E2008}</ProjectGuid>
|
||||
<ProjectVersion>19.5</ProjectVersion>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<MainSource>htmx_mustache.dpr</MainSource>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
<AppType>Console</AppType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||
<Base_Win32>true</Base_Win32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
|
||||
<Base_Win64>true</Base_Win64>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
|
||||
<Cfg_1_Win32>true</Cfg_1_Win32>
|
||||
<CfgParent>Cfg_1</CfgParent>
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
|
||||
<SanitizedProjectName>htmx_mustache</SanitizedProjectName>
|
||||
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
|
||||
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
|
||||
<DCC_E>false</DCC_E>
|
||||
<DCC_N>false</DCC_N>
|
||||
<DCC_S>false</DCC_S>
|
||||
<DCC_F>false</DCC_F>
|
||||
<DCC_K>false</DCC_K>
|
||||
</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>
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
|
||||
<VerInfo_Keys>CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName)</VerInfo_Keys>
|
||||
<Manifest_File>None</Manifest_File>
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;frxe23;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;ipstudiowinwordxp;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;DelphiCookbookListViewAppearance;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;bdertl;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;frxTee23;JclDeveloperTools;vclie;CPortLibDXE;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;Jcl;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;ipstudiowinclient;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DTKANPRPackage;DBXSybaseASADriver;CustomIPTransport;vcldsnap;CodeSiteExpressPkg;SampleListViewMultiDetailAppearancePackage;bindcomp;appanalytics;ipstudiowin;DBXInformixDriver;officeXPrt;IndyIPClient;bindcompvcl;frxDB23;vcldbx;TeeUI;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;JclVcl;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;frx23;JclContainers;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;ipstudiowinclient;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;ipstudiowin;DBXInformixDriver;officeXPrt;IndyIPClient;bindcompvcl;TeeUI;vclribbon;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
<DCC_DebugDCUs>true</DCC_DebugDCUs>
|
||||
<DCC_Optimize>false</DCC_Optimize>
|
||||
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
|
||||
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
|
||||
<DCC_RemoteDebug>true</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
<Manifest_File>None</Manifest_File>
|
||||
<DCC_RemoteDebug>false</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="WebModuleU.pas">
|
||||
<Form>WebModule1</Form>
|
||||
<DesignClass>TWebModule</DesignClass>
|
||||
</DCCReference>
|
||||
<DCCReference Include="WebSiteControllerU.pas"/>
|
||||
<DCCReference Include="DAL.pas"/>
|
||||
<DCCReference Include="..\renders\MyDataModuleU.pas">
|
||||
<Form>MyDataModule</Form>
|
||||
<DesignClass>TDataModule</DesignClass>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\htmx\MVCFramework.HTMX.pas"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
<Borland.ProjectType>Console</Borland.ProjectType>
|
||||
<BorlandProject>
|
||||
<Delphi.Personality>
|
||||
<Source>
|
||||
<Source Name="MainSource">htmx_mustache.dpr</Source>
|
||||
</Source>
|
||||
<Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k230.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp230.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k230.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
</Excluded_Packages>
|
||||
</Delphi.Personality>
|
||||
<Deployment Version="4">
|
||||
<DeployFile LocalName="bin\ServerSideViews.exe" Configuration="Debug" Class="ProjectOutput"/>
|
||||
<DeployFile LocalName="bin\htmx_mustache.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>htmx_mustache.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidClasses">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>64</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>64</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidFileProvider">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\xml</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\xml</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidGDBServer">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiv7aFile">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeMipsFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashImageDef">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStyles">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStylesV21">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values-v21</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values-v21</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Colors">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_DefaultAppIcon">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon144">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon192">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon24">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage426">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage470">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage640">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage960">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Strings">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyFramework">
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="DependencyPackage">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.bpl</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="File">
|
||||
<Platform Name="Android">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXDebug"/>
|
||||
<DeployClass Name="ProjectOSXEntitlements"/>
|
||||
<DeployClass Name="ProjectOSXInfoPList"/>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements"/>
|
||||
<DeployClass Name="ProjectiOSInfoPList"/>
|
||||
<DeployClass Name="ProjectiOSLaunchScreen"/>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iOS_AppStore1024">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_AppIcon152">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_AppIcon167">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_LaunchDark2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Notification40">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Setting58">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_SpotLight80">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_AppIcon120">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_AppIcon180">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch3x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_LaunchDark2x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_LaunchDark3x">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Notification40">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Notification60">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Setting58">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Setting87">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Spotlight120">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Spotlight80">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
|
||||
</Deployment>
|
||||
<Platforms>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
|
||||
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
|
||||
</Project>
|
@ -515,6 +515,127 @@
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXDebug"/>
|
||||
<DeployClass Name="ProjectOSXEntitlements"/>
|
||||
<DeployClass Name="ProjectOSXInfoPList"/>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements"/>
|
||||
<DeployClass Name="ProjectiOSInfoPList"/>
|
||||
<DeployClass Name="ProjectiOSLaunchScreen"/>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iOS_AppStore1024">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
|
||||
@ -715,127 +836,6 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements"/>
|
||||
<DeployClass Name="ProjectiOSInfoPList"/>
|
||||
<DeployClass Name="ProjectiOSLaunchScreen"/>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXDebug"/>
|
||||
<DeployClass Name="ProjectOSXEntitlements"/>
|
||||
<DeployClass Name="ProjectOSXInfoPList"/>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\arm64-v8a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSXARM64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOutput_Android32">
|
||||
<Platform Name="Android64">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectUWPManifest">
|
||||
<Platform Name="Win32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo150">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="UWP_DelphiLogo44">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win64">
|
||||
<RemoteDir>Assets</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
|
||||
|
@ -150,6 +150,7 @@ type
|
||||
public const
|
||||
SessionTimeout = 'sessiontimeout';
|
||||
ViewPath = 'view_path';
|
||||
ViewCache = 'view_cache';
|
||||
DefaultContentType = 'default_content_type';
|
||||
DefaultContentCharset = 'default_content_charset';
|
||||
DefaultViewFileExtension = 'default_view_file_extension';
|
||||
@ -1054,7 +1055,8 @@ begin
|
||||
if FConfig.ContainsKey(AIndex) then
|
||||
Result := FConfig.Items[AIndex]
|
||||
else
|
||||
raise EMVCConfigException.CreateFmt('Invalid config key [%s]', [AIndex]);
|
||||
Result := ''; //v3.4.1-sodium (an invalid config key returns empty string, doesn't raise an exception)
|
||||
//raise EMVCConfigException.CreateFmt('Invalid config key [%s]', [AIndex]);
|
||||
end;
|
||||
|
||||
function TMVCConfig.GetValueAsInt64(const AIndex: string): Int64;
|
||||
|
@ -60,7 +60,7 @@ uses
|
||||
MVCFramework.Serializer.Intf,
|
||||
MVCFramework.DuckTyping,
|
||||
MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes,
|
||||
MVCFramework.Serializer.JsonDataObjects;
|
||||
MVCFramework.Serializer.JsonDataObjects, MVCFramework.Serializer.Commons;
|
||||
|
||||
{$WARNINGS OFF}
|
||||
|
||||
@ -111,6 +111,7 @@ procedure TMVCMustacheViewEngine.LoadPartials;
|
||||
var
|
||||
lViewsExtension: string;
|
||||
lViewPath: string;
|
||||
lPartialName: String;
|
||||
lPartialFileNames: TArray<string>;
|
||||
I: Integer;
|
||||
begin
|
||||
@ -126,13 +127,18 @@ begin
|
||||
begin
|
||||
lViewsExtension := Config[TMVCConfigKey.DefaultViewFileExtension];
|
||||
lViewPath := Config[TMVCConfigKey.ViewPath];
|
||||
lPartialFileNames := TDirectory.GetFiles(lViewPath, '*.' + lViewsExtension);
|
||||
lPartialFileNames := TDirectory.GetFiles(lViewPath, '*.' + lViewsExtension, TSearchOption.soAllDirectories);
|
||||
FreeAndNil(fPartials);
|
||||
fPartials := TSynMustachePartials.Create;
|
||||
for I := 0 to High(lPartialFileNames) do
|
||||
begin
|
||||
fPartials.Add(TPath.GetFileNameWithoutExtension(lPartialFileNames[i]), TFile.ReadAllText(lPartialFileNames[i]));
|
||||
lPartialName := lPartialFileNames[i]
|
||||
.Remove(lPartialFileNames[i].Length - lViewsExtension.Length - 1)
|
||||
.Replace(TPath.DirectorySeparatorChar, '/');
|
||||
lPartialName := lPartialName.Remove(0, lViewPath.Length + 1);
|
||||
fPartials.Add(lPartialName, TFile.ReadAllText(lPartialFileNames[i]));
|
||||
end;
|
||||
gPartialsLoaded := True;
|
||||
gPartialsLoaded := SameText(Config[TMVCConfigKey.ViewCache], 'true');
|
||||
end;
|
||||
finally
|
||||
TMonitor.Exit(gLock);
|
||||
@ -145,43 +151,44 @@ end;
|
||||
|
||||
procedure TMVCMustacheViewEngine.PrepareModels;
|
||||
var
|
||||
lFirst: Boolean;
|
||||
lList: IMVCList;
|
||||
DataObj: TPair<string, TObject>;
|
||||
lDSPair: TPair<string, TDataSet>;
|
||||
lSJSON: string;
|
||||
lJSON: string;
|
||||
lSer: IMVCSerializer;
|
||||
lSer: TMVCJsonDataObjectsSerializer;
|
||||
lJSONModel: TJsonObject;
|
||||
begin
|
||||
if Assigned(FJSONModel) then
|
||||
if Assigned(FJSONModel) and (not Assigned(ViewModel)) and (not Assigned(ViewDataSets)) then
|
||||
begin
|
||||
// if only jsonmodel is <> nil then we take the "fast path"
|
||||
FJSONModelAsString := FJSONModel.ToJSON(False);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
{TODO -oDanieleT -cGeneral : Quite inefficient to generate JSON in this way. Why don't use a JSONObject directly?}
|
||||
if (FJSONModelAsString <> '{}') and (not FJSONModelAsString.IsEmpty) then
|
||||
Exit;
|
||||
FJSONModelAsString := '{}';
|
||||
|
||||
lSer := TMVCJsonDataObjectsSerializer.Create;
|
||||
try
|
||||
RegisterOptionalCustomTypesSerializers(lSer);
|
||||
lSJSON := '{';
|
||||
lFirst := True;
|
||||
|
||||
if Assigned(FJSONModel) then
|
||||
begin
|
||||
lJSONModel := FJSONModel.Clone as TJsonObject;
|
||||
end
|
||||
else
|
||||
begin
|
||||
lJSONModel := TJsonObject.Create;
|
||||
end;
|
||||
try
|
||||
if Assigned(ViewModel) then
|
||||
begin
|
||||
for DataObj in ViewModel do
|
||||
begin
|
||||
lList := TDuckTypedList.Wrap(DataObj.Value);
|
||||
if lList <> nil then
|
||||
lJSON := lSer.SerializeCollection(DataObj.Value)
|
||||
begin
|
||||
lSer.ListToJsonArray(lList, lJSONModel.A[DataObj.Key], TMVCSerializationType.stProperties, nil);
|
||||
end
|
||||
else
|
||||
lJSON := lSer.SerializeObject(DataObj.Value);
|
||||
if not lFirst then
|
||||
lSJSON := lSJSON + ',';
|
||||
lSJSON := lSJSON + '"' + DataObj.Key + '":' + lJSON;
|
||||
lFirst := False;
|
||||
begin
|
||||
lSer.ObjectToJsonObject(DataObj.Value, lJSONModel.O[DataObj.Key], TMVCSerializationType.stProperties, nil);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -189,16 +196,16 @@ begin
|
||||
begin
|
||||
for lDSPair in ViewDataSets do
|
||||
begin
|
||||
lJSON := lSer.SerializeDataSet(lDSPair.Value);
|
||||
if not lFirst then
|
||||
lSJSON := lSJSON + ',';
|
||||
lSJSON := lSJSON + '"' + lDSPair.Key + '":' + lJSON;
|
||||
lFirst := False;
|
||||
lSer.DataSetToJsonArray(lDSPair.Value, lJSONModel.A[lDSPair.Key], TMVCNameCase.ncAsIs, nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
lSJSON := lSJSON + '}';
|
||||
FJSONModelAsString := lSJSON;
|
||||
FJSONModelAsString := lJSONModel.ToJSON(False);
|
||||
finally
|
||||
lJSONModel.Free;
|
||||
end;
|
||||
finally
|
||||
lSer.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -1170,7 +1170,11 @@ type
|
||||
const AViewModel: TMVCViewDataObject;
|
||||
const AViewDataSets: TObjectDictionary<string, TDataSet>;
|
||||
const AContentType: string); overload; virtual;
|
||||
constructor Create(const AEngine: TMVCEngine; const AWebContext: TWebContext;
|
||||
constructor Create(
|
||||
const AEngine: TMVCEngine;
|
||||
const AWebContext: TWebContext;
|
||||
const AViewModel: TMVCViewDataObject;
|
||||
const AViewDataSets: TObjectDictionary<string, TDataSet>;
|
||||
const AJSONModel: TJSONObject;
|
||||
const AContentType: string); overload; virtual;
|
||||
destructor Destroy; override;
|
||||
@ -2721,6 +2725,7 @@ begin
|
||||
lSelectedController.MVCControllerBeforeDestroy;
|
||||
end;
|
||||
lContext.Response.ContentType := lSelectedController.ContentType;
|
||||
Result := True; //handled
|
||||
end; //if not handled by OnBeforeControllerActionMiddleware
|
||||
ExecuteAfterControllerActionMiddleware(lContext,
|
||||
lRouterControllerClazzQualifiedClassName,
|
||||
@ -3710,11 +3715,9 @@ function TMVCController.GetRenderedView(const AViewNames: TArray<string>;
|
||||
var
|
||||
lView: TMVCBaseViewEngine; lViewName: string; lStrStream: TStringStream;
|
||||
begin
|
||||
Assert(not Assigned(FViewModel), 'ViewModel must not be used when JSONModel is used');
|
||||
Assert(not Assigned(FViewDataSets), 'ViewDatasets must not be used when JSONModel is used');
|
||||
lStrStream := TStringStream.Create('', TEncoding.UTF8);
|
||||
try
|
||||
lView := FEngine.ViewEngineClass.Create(Engine, Context, JSONModel, ContentType);
|
||||
lView := FEngine.ViewEngineClass.Create(Engine, Context, FViewModel, FViewDataSets, JSONModel, ContentType);
|
||||
try
|
||||
for lViewName in AViewNames do
|
||||
begin
|
||||
@ -3754,6 +3757,14 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
{
|
||||
This useless call is required because otherwise
|
||||
the IdCustomHTTPServer.pas at line 2211 (11 alexandria)
|
||||
emits some useless HTML. Call Render('') cause
|
||||
the internal contentstream to be created so the empty
|
||||
stream is rendered and not the useless HTML.
|
||||
}
|
||||
Controller.Render(''); {required}
|
||||
Controller.ResponseStatus(MVCResponse.StatusCode);
|
||||
end;
|
||||
end;
|
||||
@ -4608,7 +4619,9 @@ end;
|
||||
|
||||
{ TMVCBaseView }
|
||||
|
||||
constructor TMVCBaseViewEngine.Create(const AEngine: TMVCEngine; const AWebContext: TWebContext;
|
||||
constructor TMVCBaseViewEngine.Create(
|
||||
const AEngine: TMVCEngine;
|
||||
const AWebContext: TWebContext;
|
||||
const AViewModel: TMVCViewDataObject;
|
||||
const AViewDataSets: TObjectDictionary<string, TDataSet>;
|
||||
const AContentType: string);
|
||||
@ -4622,11 +4635,15 @@ begin
|
||||
FOutput := EmptyStr;
|
||||
end;
|
||||
|
||||
constructor TMVCBaseViewEngine.Create(const AEngine: TMVCEngine;
|
||||
const AWebContext: TWebContext; const AJSONModel: TJSONObject;
|
||||
constructor TMVCBaseViewEngine.Create(
|
||||
const AEngine: TMVCEngine;
|
||||
const AWebContext: TWebContext;
|
||||
const AViewModel: TMVCViewDataObject;
|
||||
const AViewDataSets: TObjectDictionary<string, TDataSet>;
|
||||
const AJSONModel: TJSONObject;
|
||||
const AContentType: string);
|
||||
begin
|
||||
Create(AEngine, AWebContext, nil, nil, AContentType);
|
||||
Create(AEngine, AWebContext, AViewModel, AViewDataSets, AContentType);
|
||||
fJSONModel := AJSONModel;
|
||||
end;
|
||||
|
||||
@ -4636,7 +4653,9 @@ begin
|
||||
end;
|
||||
|
||||
function TMVCBaseViewEngine.GetRealFileName(const AViewName: string): string;
|
||||
var lFileName: string; lDefaultViewFileExtension: string;
|
||||
var
|
||||
lFileName: string;
|
||||
lDefaultViewFileExtension: string;
|
||||
begin
|
||||
lDefaultViewFileExtension := Config[TMVCConfigKey.DefaultViewFileExtension];
|
||||
lFileName := StringReplace(AViewName, '/', '\', [rfReplaceAll]);
|
||||
|
@ -1291,7 +1291,7 @@ begin
|
||||
var lFName: string := TPath.Combine(AppPath, 'customers.json');
|
||||
lDS.LoadFromFile(lFName);
|
||||
ViewDataset['customers'] := lDS;
|
||||
ViewData['customers2'] := lDS;
|
||||
ViewDataset['customers2'] := lDS;
|
||||
LoadView(['dataset_list']);
|
||||
RenderResponseStream;
|
||||
finally
|
||||
|
Loading…
Reference in New Issue
Block a user