Construyendo Aplicaciones Web Delphi en Minutos con DMVCFramework y TemplatePro
- 👉 This article is available in english too.
- 👉 Este artículo también está disponible en español.
- 👉 Questo articolo è disponibile anche in italiano.
- 👉 Este artigo também está disponível em português do Brasil.
En el acelerado mundo del desarrollo web, la velocidad y la eficiencia no son solo ventajas, son necesidades. Mientras la industria a menudo gravita hacia frameworks JavaScript complejos y cadenas de herramientas intrincadas, DMVCFramework se destaca como el proyecto Delphi más popular en GitHub por una razón convincente: entrega aplicaciones web de nivel empresarial con una simplicidad y velocidad sin precedentes.
Combinado con el potente motor de plantillas de TemplatePro y mejorado por herramientas modernas como WebStencils, este ecosistema representa un cambio de paradigma en cómo se pueden construir aplicaciones web. Exploremos cómo estas tecnologías permiten a los desarrolladores crear aplicaciones web sofisticadas en minutos, no en meses.

El Trío Poderoso: DMVCFramework, TemplatePro y WebStencils
DMVCFramework: La Base del Desarrollo Web Rápido
DMVCFramework es un framework popular y poderoso para WEB API en Delphi que soporta el desarrollo de WEB APIs RESTful y JSON-RPC. Lo que lo distingue es su notable capacidad para transformar tareas complejas de desarrollo web en operaciones simples e intuitivas.
Esto es lo que hace excepcional a DMVCFramework:
Estabilidad Lista para Producción: Utilizado por proyectos pequeños/medianos/grandes desde 2010, DMVCFramework ha demostrado su valía en entornos de alto tráfico. Algunas de las WEB APIs Delphi de mayor tráfico (RESTful o JSONRPC) están impulsadas por DMVCFramework.
Desarrollo Instantáneo: Puedes crear un servidor RESTful completo en un par de clics. El asistente integrado hace que la creación de proyectos sea casi instantánea.
Implementación Flexible: Ya sea que necesites un servidor independiente, módulo Apache o extensión ISAPI, DMVCFramework se adapta a las necesidades de tu infraestructura.
Ecosistema Rico: Con más de 100 ejemplos y documentación completa, los desarrolladores pueden ser productivos inmediatamente.
TemplatePro: Plantillas Modernas Simplificadas
TemplatePro es un motor de plantillas moderno y versátil diseñado para simplificar la generación dinámica de HTML, contenido de correo electrónico y archivos de texto. Con una sintaxis inspirada en sistemas populares como Jinja y Smarty, proporciona características poderosas que incluyen bloques condicionales, bucles, herencia de plantillas y soporte de datos JSON.
Características Clave:
- Sintaxis Intuitiva: Utiliza la notación familiar
{{}}para expresiones y lógica - Herencia de Plantillas: Construye diseños y componentes reutilizables
- Filtros Personalizados: Extiende la funcionalidad con transformaciones de datos específicas del dominio
- Integración JSON: Maneja sin problemas datos de API y objetos complejos
- Rendimiento: Las plantillas compiladas aseguran una ejecución rápida
La Documentación Oficial de TemplatePro está disponible aquí
WebStencils: El Motor de Plantillas de RAD Studio
WebStencils es el motor de plantillas nativo de RAD Studio 12.2 que proporciona capacidades de scripting del lado del servidor para extender aplicaciones WebBroker y RAD Server. WebStencils representa el reconocimiento de Embarcadero de la importancia de los motores de plantillas modernos en el desarrollo web.
Ambos motores soportan lógica condicional, bucles, herencia de plantillas y mecanismos de inclusión. Sin embargo, TemplatePro proporciona algunas características únicas como filtros personalizados, manejo nativo de JSON y compilación opcional. El objetivo principal de WebStencils es extender significativamente las tecnologías web existentes en RAD Studio al convertir cualquier motor de Web Service en una herramienta completa de Web Site y Web Service.
Si estás interesado en el motor WebStencils, recomiendo encarecidamente la Guía Gratuita WebStencils and HTMX: Free Guide to Fast Web Development de mi amigo Antonio Zapater.
Inicio Rápido: De la Descarga a la Aplicación Web en Ejecución en 2 Minutos
La belleza de DMVCFramework y TemplatePro radica en su usabilidad inmediata. Olvídate de procedimientos de configuración complejos: puedes tener una aplicación web completamente funcional ejecutándose en menos de 2 minutos.
Paso 1: Descargar y Ejecutar
Simplemente descarga el proyecto de inicio rápido y estarás listo para comenzar:
- Descarga el archivo zip QuickStart
- Descomprímelo en una carpeta que te guste
- Abre el proyecto
dmvcframework_templatepro_htmx_quickstart.dprojen Delphi y presiona F9 - ¡Eso es todo! Tu servidor web está ejecutándose en localhost:8080
A partir de ahora puedes renombrar archivos y agregar las funcionalidades que tu proyecto requiere.
El proyecto de inicio rápido incluye una aplicación web completa con:
- Servidor DMVCFramework preconfigurado listo para ejecutar
- Plantillas TemplatePro ya configuradas
- Datos de ejemplo y controladores que demuestran las mejores prácticas
- Interfaz web responsiva usando Bootstrap
- Ejemplos funcionales de todas las características principales
Paso 2: Explora Lo Que Ya Está Construido
Abre el proyecto y encontrarás un sistema de gestión de clientes completamente funcional:
// ControllerU.pas - Already implemented!
unit ControllerU;
interface
uses
MVCFramework, MVCFramework.Commons, MVCFramework.Serializer.Commons, System.Generics.Collections;
type
[MVCPath]
TMyController = class(TMVCController)
public
[MVCPath]
[MVCHTTPMethod([httpGET])]
[MVCProduces(TMVCMediaType.TEXT_HTML)]
function Index: String;
[MVCPath('/reversedstrings')]
[MVCHTTPMethod([httpGET])]
[MVCProduces(TMVCMediaType.TEXT_PLAIN)]
function GetReversedString(const [MVCFromQueryString('value','')] Value: String): String;
end;
implementation
uses
System.StrUtils, System.SysUtils, MVCFramework.Logger;
function TMyController.Index: String;
begin
Result := RenderView('index');
end;
function TMyController.GetReversedString(const Value: String): String;
begin
ViewData['reversed_string'] := System.StrUtils.ReverseString(Value.Trim);
Result := RenderView('partials/reversed');
end;
end.
Paso 3: Ver TemplatePro en Acción
El inicio rápido incluye plantillas funcionales que puedes examinar y modificar:
templates/index.html (incluido en el inicio rápido):
{{extends "_layout.html"}}
{{block "body"}}
<div class="row">
<div class="col">
<div class="text-center mt-5">
<h1>DMVCFramework + TemplatePro + HTMX</h1>
<p class="lead">A complete project boilerplate built with Bootstrap</p>
<p>Bootstrap v5.3.3</p>
</div>
</div>
</div>
<div class="row mt-5">
<div class="col col-3 offset-3">
<div class="mb-3">
<input type="text" name="value" class="form-control" id="exampleFormControlInput1"
placeholder="Write something here" value="Hello World">
</div>
</div>
<div class="col col-2">
<button type="button" hx-get="/reversedstrings" hx-include='input' hx-target="#result"
class="btn btn-primary">Reverse it!</button>
</div>
</div>
<div class="row">
<div class="col col-5 offset-3">
<div id="result" class="alert alert-primary" role="alert">
{{include "partials/reversed.html"}}
</div>
</div>
</div>
{{endblock}}
Paso 4: Personalización Instantánea
¿Quieres ver tus cambios inmediatamente? El inicio rápido está diseñado para retroalimentación instantánea:
- Modifica una plantilla - Edita
templates/index.html - Actualiza el navegador - Ve los cambios inmediatamente (¡no se necesita compilación para las plantillas!)
- Crea nuevos endpoints - Sigue los patrones de controlador existentes
templates/_layout.hmtl (también incluido):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="description" content="A simple DMVCFramework + TemplatePro + HTMX Template for new projects.">
<meta name="author" content="Daniele Teti">
<title>DMVCFramework TemplatePro HTMX Quick Start</title>
<!-- Latest compiled and minified CSS -->
<script src="/assets/js/htmx.min.js"></script>
<link href="/assets/bootstrap-5.3.3/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<link rel="stylesheet" href="/assets/css/style.css"/>
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
<link rel="manifest" href="/assets/site.webmanifest" />
</head>
<body>
<!-- Responsive navbar-->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">Start Bootstrap</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Link</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#"
role="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
{{block "body"}}{{endblock}}
</div>
<!-- Bootstrap core JS-->
<script src="/assets/bootstrap-5.3.3/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<!-- Core theme JS-->
<script src="/assets/js/scripts.js"></script>
</body>
</html>
Ahora es momento para otra foto completamente no relacionada… 😁

Características Avanzadas de TemplatePro en Acción
Trabajando con Datos JSON
TemplatePro sobresale en el manejo de datos JSON de APIs:
function TMyController.GetCustomers: String;
begin
//Let's create a dataset containing 15 random people we consider as customers.
//This dataset is generated by the "Delphi Fake Data Utils" project available here https://github.com/danieleteti/delphi_fake_data_utils
var lDS := ToFree<TDataSet>(GetPeople(15));
var lJSON := ToFree<TJSONObject>(TJSONObject.Create);
//calculate customers avg age
lDS.First;
var lAgeCumulative := 0;
_.ForEachRecord(lDS,
procedure(const DS: TDataSet)
begin
lAgeCumulative := lAgeCumulative + YearsBetween(Now, lDS.FieldByName('dob').AsDateTime);
end);
var lAvgAge := lAgeCumulative / lDS.RecordCount;
lDS.First;
// end - stats
lJSON.A['customers'] := lDS.AsJDOJSONArray();
lJSON.F['avg_age'] := lAvgAge;
ViewData['data'] := lJSON;
Result := RenderView('index');
end;
Plantilla de Directorio de Clientes (customers.html):
{{extends "_layout.html"}}
{{block "body"}}
<h2 class="mb-4">Customers Directory</h2>
<!-- TemplatePro Template for Dataset Table -->
{{if data.customers}}
<div class="table-container">
<table class="table table-striped table-hover mb-0">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Code</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Country</th>
<th scope="col">Date of Birth</th>
<th scope="col">Age</th>
</tr>
</thead>
<tbody>
{{for customer in data.customers}}
<tr {{if customer.@@odd}}class="table-light"{{endif}}>
<th scope="row">{{:customer.@@index}}</th>
<td>
<span class="badge bg-secondary">{{:customer.code}}</span>
</td>
<td>{{:customer.first_name|capitalize}}</td>
<td>{{:customer.last_name|uppercase}}</td>
<td>
<span class="badge bg-primary badge-country">{{:customer.country|uppercase}}</span>
</td>
<td>{{:customer.dob}}</td>
<td>
{{if customer.dob}}
<small class="text-muted">
<!-- Calculate age - you'd implement this as a custom filter -->
{{:customer.dob|age}} years
</small>
{{else}}
<small class="text-muted">N/A</small>
{{endif}}
</td>
</tr>
{{endfor}}
</tbody>
</table>
</div>
<!-- Dataset Statistics -->
<div class="row mt-4">
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">{{:data.customers|count}}</h5>
<p class="card-text">Total Customers</p>
</div>
</div>
</div>
<div class="offset-md-4 col-md-4">
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">{{:data.avg_age|round,-2}} years</h5>
<p class="card-text">Average Age</p>
</div>
</div>
</div>
</div>
{{else}}
<!-- Empty State -->
<div class="alert alert-info text-center" role="alert">
<h4 class="alert-heading">No Data Available</h4>
<p>The employee dataset is empty or not loaded.</p>
<hr>
<p class="mb-0">Please check your data source and try again.</p>
</div>
{{endif}}
<!-- Action Buttons -->
<div class="d-flex justify-content-between mt-4">
<button class="btn btn-outline-secondary" onclick="window.print()">
Print Table
</button>
<div>
<button class="btn btn-success me-2" onclick="exportToCSV()">
Export CSV
</button>
<button class="btn btn-primary" onclick="addEmployee()">
Add Employee
</button>
</div>
</div>
</div>
<script>
function exportToCSV() {
// CSV export functionality
alert('CSV export would be implemented here');
}
function addEmployee() {
// Add employee functionality
alert('Add employee form would open here');
}
</script>
{{endblock}}
Filtros Personalizados para Lógica de Dominio
Crea filtros especializados para tu dominio de negocio:
// Custom filter for "age" expressed as in "I'm x years old"
function Age(const Value: TValue; const Parameters: TArray<TFilterParameter>): TValue;
begin
//DOB is a string formatted as yyyy-mm-dd
Result := YearsBetween(Now, ISODateToDate(Value.AsString));
end;
// Register filters
procedure TemplateProContextConfigure;
begin
TTProConfiguration.OnContextConfiguration := procedure(const CompiledTemplate: ITProCompiledTemplate)
begin
// These filters will be available to the TemplatePro views as if they were the standard ones
CompiledTemplate.AddFilter('age', Age);
end;
end;
Uso en plantillas:
{{if customer.dob}}
<small class="text-muted">
<!-- Calculate age - you'd implement this as a custom filter -->
{{:customer.dob|age}} years
</small>
{{else}}
<small class="text-muted">N/A</small>
{{endif}}
Aquí está la página de ejemplo resultante.

Funciones de Plantilla para Lógica Compleja
Las funciones proporcionan aún más poder y pueden usarse para implementar lógica compleja.
Integración con HTMX
Las páginas HTMX pueden beneficiarse de la generación de código del lado del servidor y conectarse a servidores REST con respecto a las actualizaciones de contenido. Las tecnologías web de Delphi pueden ofrecer generación de páginas y APIs REST a un nivel de muy alta calidad.
<!-- HTMX-powered dynamic content -->
<div id="customer-list">
{{include "partials/customer-list.html"}}
</div>
<button hx-get="/api/customers"
hx-target="#customer-list"
hx-swap="innerHTML">
Refresh Customers
</button>
<form hx-post="/api/customers"
hx-target="#customer-list"
hx-swap="innerHTML">
<input name="name" placeholder="Customer Name" required>
<input name="email" placeholder="Email" required>
<button type="submit">Add Customer</button>
</form>
TemplatePro soporta Características Empresariales como:
- Plantillas Compiladas para máximo rendimiento y menor carga de CPU
- Autenticación y Autorización: las plantillas pueden tener acceso a los roles de usuario
- Manejo de Errores: en caso de errores no manejados se activa el manejo de errores predeterminado (consulta el ejemplo \samples\custom_exception_handling_using_controller)
Recursos de Aprendizaje y Próximos Pasos
Comenzando Inmediatamente
La forma más rápida de comenzar es usar el asistente de DMVCFramework en el IDE de Delphi. DMVCFramework permite crear servidores RESTful poderosos sin esfuerzo. Puedes crear un servidor RESTful completo en un par de clics.
Comunidad y Soporte
- Grupo de soporte gratuito en https://www.facebook.com/groups/delphimvcframework con más de 6000 miembros activos proporciona una comunidad activa para desarrolladores.
- Suscripción premium PATREON para ayuda directa en Discord, ejemplos avanzados y artículos y videos en profundidad sobre dmvcframework en https://www.patreon.com/c/delphimvcframework
- Capacitaciones oficiales de bit Time Professionals sobre DMVCFramework, HTMX y muchos otros temas.
Acerca de WebStencils
Para una cobertura completa de WebStencils e integración con HTMX, recomendamos encarecidamente descargar el White Paper gratuito de Antonio Zapater disponible en el blog de Embarcadero. Esta guía proporciona cobertura en profundidad de:
- Técnicas avanzadas de scripting de WebStencils
- Patrones de integración con HTMX
- Estrategias de implementación empresarial
- Optimización del rendimiento
- Mejores prácticas de seguridad
Conclusión
La combinación de DMVCFramework y TemplatePro (o WebStencils) representa un paradigma poderoso para el desarrollo web rápido. Mientras otros frameworks requieren procesos de construcción complejos, conocimiento extenso de JavaScript y procedimientos de implementación intrincados, este stack basado en Delphi ofrece:
Velocidad: De concepto a producción en minutos, no en semanas Simplicidad: Sintaxis intuitiva que los desarrolladores pueden dominar rápidamente Poder: Características de nivel empresarial sin complejidad de nivel empresarial Flexibilidad: Implementa en cualquier lugar, integra con cualquier cosa Estabilidad: Probado en batalla en entornos de producción en todo el mundo
Como lo reveló un análisis de Embarcadero, DMVCFramework es el proyecto Delphi más popular para WebAPI y WebApp en GitHub desde 2017, y su integración con motores de plantillas modernos como TemplatePro y WebStencils solo fortalece su posición como la solución de referencia para el desarrollo web rápido.
Ya sea que estés construyendo herramientas internas, aplicaciones orientadas al cliente o APIs empresariales, este stack proporciona el equilibrio perfecto de productividad y profesionalismo. La curva de aprendizaje es suave, la documentación es completa y la comunidad es solidaria.
Para los desarrolladores cansados de cadenas de herramientas complejas y soluciones sobreingeniadas, DMVCFramework con TemplatePro ofrece un refrescante retorno a la simplicidad sin sacrificar capacidad. En un mundo donde el desarrollo web a menudo se siente innecesariamente complicado, estas herramientas prueban que a veces la mejor solución es también la más simple.
¿Listo para experimentar la velocidad y simplicidad por ti mismo? Comienza con el asistente de DMVCFramework, explora los ejemplos, y sumérgete en los recursos gratuitos disponibles. Tu próxima aplicación web está a solo minutos de distancia.
Comments
comments powered by Disqus