Skip to content

Commit

Permalink
NEW sample: htmx_website
Browse files Browse the repository at this point in the history
  • Loading branch information
danieleteti committed Jul 2, 2024
1 parent 2758b2b commit 6d22cf6
Show file tree
Hide file tree
Showing 13 changed files with 1,354 additions and 0 deletions.
66 changes: 66 additions & 0 deletions samples/htmx_website/ControllerU.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
unit ControllerU;

interface

uses
MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons,
System.Generics.Collections;

type
[MVCPath]
TMyController = class(TMVCController)
protected
procedure OnBeforeAction(AContext: TWebContext; const AActionName: string;
var AHandled: Boolean); override;
public
[MVCPath]
[MVCHTTPMethod([httpGET])]
function Home: String;

[MVCPath('/users')]
[MVCHTTPMethod([httpGET])]
function Users: String;

[MVCPath('/posts')]
[MVCHTTPMethod([httpGET])]
function Posts: String;

[MVCPath('/customers')]
[MVCHTTPMethod([httpGET])]
function Customers: String;
end;

implementation

uses
System.StrUtils, System.SysUtils, MVCFramework.Logger, MVCFramework.HTMX;

function TMyController.Customers: String;
begin
Result := Page(['pages/customers'], not Context.Request.IsHTMX);
end;

function TMyController.Home: String;
begin
Result := Page(['pages/home'], not Context.Request.IsHTMX);
end;

procedure TMyController.OnBeforeAction(AContext: TWebContext;
const AActionName: string; var AHandled: Boolean);
begin
inherited;
SetPagesCommonHeaders(['_header']);
SetPagesCommonFooters(['_footer']);
end;

function TMyController.Posts: String;
begin
Result := Page(['pages/posts'], not Context.Request.IsHTMX);
end;

function TMyController.Users: String;
begin
Result := Page(['pages/users'], not Context.Request.IsHTMX);
end;

end.
31 changes: 31 additions & 0 deletions samples/htmx_website/HelpersU.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
unit HelpersU;

interface


type
TMyMustacheHelpers = class sealed
public
class procedure MyHelper1(const Value: variant; out Result: variant);
class procedure MyHelper2(const Value: variant; out Result: variant);
end;

implementation

uses
MVCFramework.View.Renderers.Mustache, System.SysUtils;

{ TMyMustacheHelpers }

class procedure TMyMustacheHelpers.MyHelper1(const Value: variant; out Result: variant);
begin
Result := Value + ' (I''m The MyHelper1)';
end;

class procedure TMyMustacheHelpers.MyHelper2(const Value: variant; out Result: variant);
begin
Result := Value + ' (I''m The MyHelper2)';
end;


end.
7 changes: 7 additions & 0 deletions samples/htmx_website/WebModuleU.dfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object MyWebModule: TMyWebModule
OnCreate = WebModuleCreate
OnDestroy = WebModuleDestroy
Actions = <>
Height = 230
Width = 415
end
87 changes: 87 additions & 0 deletions samples/htmx_website/WebModuleU.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
unit WebModuleU;

interface

uses
System.SysUtils,
System.Classes,
Web.HTTPApp,
MVCFramework;

type
TMyWebModule = class(TWebModule)
procedure WebModuleCreate(Sender: TObject);
procedure WebModuleDestroy(Sender: TObject);
private
fMVC: TMVCEngine;
end;

var
WebModuleClass: TComponentClass = TMyWebModule;

implementation

{$R *.dfm}

uses
System.IOUtils,
MVCFramework.Commons,
MVCFramework.View.Renderers.Mustache,
MVCFramework.Middleware.ActiveRecord,
MVCFramework.Middleware.StaticFiles,
MVCFramework.Middleware.Analytics,
MVCFramework.Middleware.Trace,
MVCFramework.Middleware.CORS,
MVCFramework.Middleware.ETag,
MVCFramework.Middleware.Compression, ControllerU;

procedure TMyWebModule.WebModuleCreate(Sender: TObject);
begin
FMVC := TMVCEngine.Create(Self,
procedure(Config: TMVCConfig)
begin
// 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', 'html');
//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);

// Controllers
FMVC.AddController(TMyController);
// Controllers - END

// Server Side View
FMVC.SetViewEngine(TMVCMustacheViewEngine);
// Server Side View - END

// Middleware
// Middleware - END

end;

procedure TMyWebModule.WebModuleDestroy(Sender: TObject);
begin
FMVC.Free;
end;

end.
5 changes: 5 additions & 0 deletions samples/htmx_website/bin/templates/_footer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
</main>

</body>

</html>
19 changes: 19 additions & 0 deletions samples/htmx_website/bin/templates/_header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.2/tailwind.min.css" />
<script src="https://unpkg.com/htmx.org@latest"></script>
<title>HTMX App</title>
</head>

<body class="bg-gray-200" hx-boost="true">
<div class="flex h-screen">
<!-- Side Navigation -->
{{>partials/sidenav}}
<!-- Main Content Area -->
<main class="w-full bg-white p-4" id="main">

1 change: 1 addition & 0 deletions samples/htmx_website/bin/templates/pages/customers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1 class="text-2xl font-bold mb-4">Customers</h1>
1 change: 1 addition & 0 deletions samples/htmx_website/bin/templates/pages/home.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1 class="text-2xl font-bold mb-4">HTMX WebSite</h1>
1 change: 1 addition & 0 deletions samples/htmx_website/bin/templates/pages/posts.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1 class="text-2xl font-bold mb-4">Posts</h1>
1 change: 1 addition & 0 deletions samples/htmx_website/bin/templates/pages/users.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1 class="text-2xl font-bold mb-4">Users</h1>
6 changes: 6 additions & 0 deletions samples/htmx_website/bin/templates/partials/sidenav.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div class="w-56 bg-gray-800 text-white p-4" hx-target="#main">
<a hx-get="/" hx-push-url="true" class="block py-2 px-4 text-white hover:bg-gray-600" style="cursor: pointer;">Home</a>
<a hx-get="/users" hx-push-url="true" class="block py-2 px-4 text-white hover:bg-gray-600" style="cursor: pointer;">Users</a>
<a hx-get="/posts" hx-push-url="true" class="block py-2 px-4 text-white hover:bg-gray-600" style="cursor: pointer;">Posts</a>
<a hx-get="/customers" hx-push-url="true" class="block py-2 px-4 text-white hover:bg-gray-600" style="cursor: pointer;">Customers</a>
</div>
85 changes: 85 additions & 0 deletions samples/htmx_website/htmx_website.dpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
program htmx_website;

{$APPTYPE CONSOLE}

uses
System.SysUtils,
Web.ReqMulti,
Web.WebReq,
Web.WebBroker,
IdContext,
IdHTTPWebBrokerBridge,
MVCFramework,
MVCFramework.Logger,
MVCFramework.DotEnv,
MVCFramework.Commons,
MVCFramework.View.Renderers.Mustache,
mormot.core.mustache,
MVCFramework.Signal,
ControllerU in 'ControllerU.pas',
HelpersU in 'HelpersU.pas',
WebModuleU in 'WebModuleU.pas' {MyWebModule: TWebModule};

{$R *.res}

procedure RunServer(APort: Integer);
var
LServer: TIdHTTPWebBrokerBridge;
begin
LServer := TIdHTTPWebBrokerBridge.Create(nil);
try
LServer.OnParseAuthentication := TMVCParseAuthentication.OnParseAuthentication;
LServer.DefaultPort := APort;
LServer.KeepAlive := dotEnv.Env('dmvc.indy.keep_alive', True);
LServer.MaxConnections := dotEnv.Env('dmvc.webbroker.max_connections', 0);
LServer.ListenQueue := dotEnv.Env('dmvc.indy.listen_queue', 500);
LServer.Active := True;
LogI('Listening on port ' + APort.ToString);
LogI('Application started. Press Ctrl+C to shut down.');
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;
UseConsoleLogger := True;

LogI('** DMVCFramework Server ** build ' + DMVCFRAMEWORK_VERSION);

try
if WebRequestHandler <> nil then
WebRequestHandler.WebModuleClass := WebModuleClass;

WebRequestHandlerProc.MaxConnections := dotEnv.Env('dmvc.handler.max_connections', 1024);

{$IF CompilerVersion >= 34} //SYDNEY+
if dotEnv.Env('dmvc.profiler.enabled', false) then
begin
Profiler.ProfileLogger := Log;
Profiler.WarningThreshold := dotEnv.Env('dmvc.profiler.warning_threshold', 2000);
end;
{$ENDIF}

// Project specific Mustache helpers
TMVCMustacheHelpers.OnLoadCustomHelpers := procedure(var MustacheHelpers: TSynMustacheHelpers)
begin
TSynMustache.HelperAdd(MustacheHelpers, 'MyHelper1', TMyMustacheHelpers.MyHelper1);
TSynMustache.HelperAdd(MustacheHelpers, 'MyHelper2', TMyMustacheHelpers.MyHelper2);
end;

RunServer(dotEnv.Env('dmvc.server.port', 8080));
except
on E: Exception do
LogF(E.ClassName + ': ' + E.Message);
end;
end.
Loading

0 comments on commit 6d22cf6

Please sign in to comment.