Creador de proyectos HTML, PHP y SQLite
Genera una base de proyecto web con interfaz HTML, API PHP y esquema SQLite a partir de una descripción en español. Permite revisar y descargar los archivos generados.
Preview Mode
This is a preview with sample data. The template uses placeholders like
which will be replaced with actual agent data.
About This Template
Creador de proyectos HTML, PHP y SQLite is a browser-executable AI agent template built on AgentOp. It runs entirely in the browser using Python (via Pyodide) and can be deployed without a server — just download the generated HTML file and open it locally or host it anywhere.
Template Metadata
- Slug
- creador-de-proyectos-html-php-y-sqlite
- Created By
- luan920530
- Created
- Oct 25, 2026
- Usage Count
- 1
Tags
Code Statistics
- HTML Lines
- 52
- CSS Lines
- 1
- JS Lines
- 124
- Python Lines
- 44
Source Code
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ agent_name }}</title>
<style>{{ css_code }}</style>
</head>
<body>
<div class="app-shell">
<header class="masthead">
<span class="eyebrow">TALLER DE APLICACIONES WEB</span>
<h1>🧩 {{ agent_name }}</h1>
<p>De una idea a los archivos iniciales de una aplicación HTML, PHP y SQLite.</p>
</header>
<main class="workspace">
<section class="panel brief-panel" aria-labelledby="brief-title">
<div class="panel-heading"><span class="step">01</span><div><h2 id="brief-title">Define tu proyecto</h2><p>Explica qué debe hacer y qué datos necesita guardar.</p></div></div>
<form id="project-form" novalidate>
<label for="project-name">Nombre de la aplicación</label>
<input id="project-name" type="text" maxlength="80" placeholder="Por ejemplo: Biblioteca del barrio" required>
<label for="project-brief">¿Qué hará la aplicación?</label>
<textarea id="project-brief" rows="7" maxlength="4500" placeholder="Por ejemplo: registrar libros, buscar por título y eliminar entradas..." required></textarea>
<label for="data-fields">Datos que quieres guardar <span class="optional">(opcional)</span></label>
<textarea id="data-fields" rows="3" maxlength="1200" placeholder="Por ejemplo: título, autor, año de publicación"></textarea>
<div class="form-actions"><button id="generate-button" type="submit">✨ Crear archivos del proyecto</button><button id="reset-button" type="button" class="secondary">Limpiar proyecto</button></div>
<p id="status" class="status" role="status" aria-live="polite">Inicializando el taller…</p>
<p id="error" class="error hidden" role="alert"></p>
</form>
</section>
<section class="panel output-panel" aria-labelledby="output-title">
<div class="panel-heading"><span class="step">02</span><div><h2 id="output-title">Archivos del proyecto</h2><p>Inspecciona el código y descarga el resultado.</p></div></div>
<div id="empty-state" class="empty-state">
<div class="empty-symbol">📂</div><h3>Tu proyecto empieza aquí</h3>
<p>Completa la descripción para generar una base que incluya:</p>
<ul><li>Una interfaz HTML para tus usuarios.</li><li>Un endpoint PHP para las operaciones.</li><li>Un esquema SQL compatible con SQLite.</li><li>Indicaciones para ejecutarlo localmente.</li></ul>
</div>
<div id="output-content" class="hidden">
<div class="file-toolbar"><label for="file-select">Archivo para revisar</label><select id="file-select" aria-label="Archivo del proyecto para revisar"><option value="full">Resultado completo</option></select></div>
<pre id="code-view" class="code-view" tabindex="0"></pre>
<div class="download-actions"><button id="download-file" type="button" class="secondary">⬇ Descargar archivo seleccionado</button><button id="download-all" type="button">⬇ Descargar proyecto completo</button></div>
<p class="hint">El proyecto completo se descarga como texto. Revisa el código antes de usarlo y sirve PHP desde un servidor; abrir el HTML como archivo local no ejecuta PHP.</p>
</div>
</section>
</main>
</div>
<div id="loading-overlay" class="loading-overlay hidden" role="status" aria-live="polite"><div class="loading-card"><span class="spinner" aria-hidden="true"></span><strong>Construyendo tu proyecto…</strong><span>Preparando HTML, PHP y SQLite.</span></div></div>
<script>{{ js_code }}</script>
</body>
</html>
:root{--bg:#f3f6f5;--paper:#fff;--ink:#18312c;--muted:#637771;--line:#dce5e0;--accent:#146e5a;--accent-hover:#0e5545;--soft:#e7f4ed;--error:#a02d35;--code:#122921;--radius:18px;--shadow:0 14px 40px rgba(20,55,43,.08);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--ink)}*{box-sizing:border-box}body{margin:0;background:var(--bg);min-height:100vh}.hidden{display:none!important}.app-shell{max-width:1500px;margin:0 auto;padding:38px 34px 60px}.masthead{padding:12px 2px 28px}.eyebrow{font-size:.76rem;letter-spacing:.17em;font-weight:800;color:var(--accent)}h1{font-size:clamp(2rem,3vw,3.1rem);letter-spacing:-.04em;margin:10px 0}h2,h3,p{margin-top:0}.masthead p,.panel-heading p,.hint{color:var(--muted)}.workspace{display:grid;grid-template-columns:minmax(330px,.9fr) minmax(440px,1.1fr);gap:22px;align-items:start}.panel{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:27px;min-width:0}.panel-heading{display:flex;gap:14px;margin-bottom:22px}.panel-heading h2{margin:0 0 5px;font-size:1.24rem}.panel-heading p{margin:0;font-size:.9rem}.step{background:var(--soft);color:var(--accent);border-radius:10px;padding:8px;font-size:.78rem;font-weight:800;height:max-content}label{display:block;font-weight:700;font-size:.88rem;margin:17px 0 8px}.optional{font-weight:400;color:var(--muted)}input,textarea,select{width:100%;border:1px solid #cbd9d2;border-radius:11px;padding:12px 14px;background:white;color:var(--ink);font:inherit}textarea{resize:vertical;line-height:1.5}input::placeholder,textarea::placeholder{color:#84948d}button{font:inherit;font-weight:700;border-radius:11px;border:1px solid var(--accent);padding:12px 16px;background:var(--accent);color:white;cursor:pointer;transition:background .15s,transform .15s}button:hover:not(:disabled){background:var(--accent-hover)}button:active:not(:disabled){transform:translateY(1px)}button.secondary{background:#fff;color:var(--accent)}button.secondary:hover:not(:disabled){background:var(--soft)}button:disabled{opacity:.5;cursor:not-allowed}button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,.code-view:focus-visible{outline:3px solid #70c7a8;outline-offset:3px}.form-actions,.download-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px}.status{font-size:.85rem;color:var(--muted);margin:16px 0 0}.error{color:var(--error);background:#fff0f0;border:1px solid #efc6c6;border-radius:10px;padding:10px 12px;margin:14px 0 0;font-size:.9rem}.empty-state{border:1px dashed #b4cfc0;border-radius:14px;background:#f7fbf8;padding:24px}.empty-symbol{font-size:2rem;margin-bottom:10px}.empty-state h3{margin-bottom:6px}.empty-state p{color:var(--muted)}.empty-state ul{padding-left:21px;margin:12px 0 0;line-height:1.9}.file-toolbar{display:flex;align-items:center;gap:13px;flex-wrap:wrap;margin-bottom:12px}.file-toolbar label{margin:0;white-space:nowrap}.file-toolbar select{max-width:290px}.code-view{margin:0;background:var(--code);color:#dff5e7;border-radius:12px;padding:20px;line-height:1.55;min-height:360px;max-height:650px;overflow:auto;white-space:pre;font-size:.82rem;tab-size:2}.hint{font-size:.82rem;line-height:1.5;margin:14px 0 0}.loading-overlay{position:fixed;inset:0;background:rgba(14,35,29,.54);display:grid;place-items:center;z-index:20;padding:20px}.loading-card{background:white;border-radius:18px;padding:32px;display:flex;flex-direction:column;align-items:center;gap:11px;text-align:center;box-shadow:var(--shadow)}.loading-card span:last-child{color:var(--muted)}.spinner{width:36px;height:36px;border:4px solid #d8eae0;border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:1200px){.workspace{grid-template-columns:1fr 1fr}.app-shell{padding:28px 22px}}@media(max-width:768px){.workspace{grid-template-columns:1fr}.app-shell{padding:18px 14px 40px}.panel{padding:20px}.code-view{min-height:280px;max-height:450px}.download-actions button,.form-actions button{flex:1 1 100%}}
(() => {
'use strict';
const el = id => document.getElementById(id);
const form = el('project-form');
const generate = el('generate-button');
const reset = el('reset-button');
const status = el('status');
const error = el('error');
const overlay = el('loading-overlay');
const empty = el('empty-state');
const output = el('output-content');
const select = el('file-select');
const code = el('code-view');
const downloadFile = el('download-file');
const downloadAll = el('download-all');
let ready = false;
let busy = false;
let fullResult = '';
let files = {};
const escapeHtml = value => String(value).replace(/[&<>"']/g, ch => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[ch]));
function showError(message) { error.innerHTML = escapeHtml(message); error.classList.remove('hidden'); }
function clearError() { error.textContent = ''; error.classList.add('hidden'); }
function localProvider() { return /local|wllama|browser/.test(String(window.PROVIDER || '').toLowerCase()); }
function modelLoaded() { return !localProvider() || !!(window.agentManager && window.agentManager.isLoaded); }
function refreshStatus() {
generate.disabled = busy || !ready || !modelLoaded();
reset.disabled = busy;
select.disabled = busy || !fullResult;
downloadFile.disabled = busy || !fullResult;
downloadAll.disabled = busy || !fullResult;
status.textContent = busy ? 'Generando los archivos del proyecto…' : !ready ? 'Inicializando Python en el navegador…' : !modelLoaded() ? 'Carga un modelo desde la barra superior para crear el proyecto.' : 'Listo para crear tu proyecto HTML, PHP y SQLite.';
}
function stripFence(text) {
return text.trim().replace(/^```[^\n]*\n/, '').replace(/\n?```\s*$/, '').trim();
}
function parseFiles(text) {
const parsed = {};
const marker = /^[ \t]*(?:#{1,3}[ \t]*)?===[ \t]*(index\.html|app\.php|schema\.sql)[ \t]*===[ \t]*$/gim;
const found = [...text.matchAll(marker)];
found.forEach((match, index) => {
const end = index + 1 < found.length ? found[index + 1].index : text.length;
const body = stripFence(text.slice(match.index + match[0].length, end));
if (body) parsed[match[1].toLowerCase()] = body;
});
return parsed;
}
function render() {
empty.classList.toggle('hidden', !!fullResult);
output.classList.toggle('hidden', !fullResult);
const chosen = select.value;
code.textContent = chosen === 'full' ? fullResult : (files[chosen] || fullResult);
downloadFile.textContent = chosen === 'full' ? '⬇ Descargar resultado completo' : '⬇ Descargar ' + chosen;
refreshStatus();
}
function save(filename, text, mime) {
const url = URL.createObjectURL(new Blob([text], {type:mime}));
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
link.remove();
setTimeout(() => URL.revokeObjectURL(url), 30000);
}
function setupGuide() {
return '\n\nGUÍA DE EJECUCIÓN\n1. Guarda index.html, app.php y schema.sql en una carpeta pública servida por PHP.\n2. Activa PDO_SQLITE y SQLITE3 en PHP.\n3. Ejecuta php -S localhost:8000 desde esa carpeta y abre http://localhost:8000/index.html.\n4. El PHP debe crear la base SQLite fuera del directorio público y aplicar schema.sql (o un esquema equivalente) antes del primer uso. Revisa la ruta y los permisos según tu alojamiento.\n5. Revisa y prueba el código generado antes de publicarlo. No abras index.html con file:// para probar las peticiones a PHP.\n';
}
form.addEventListener('submit', async event => {
event.preventDefault();
clearError();
const name = el('project-name').value.trim();
const brief = el('project-brief').value.trim();
const fields = el('data-fields').value.trim();
if (!name || !brief) { showError('Escribe el nombre y la descripción de la aplicación.'); return; }
if (!ready || !window.pyodide) { showError('El entorno Python aún se está iniciando. Inténtalo de nuevo en un momento.'); return; }
if (!modelLoaded()) { showError('Carga un modelo desde la barra superior antes de crear el proyecto.'); return; }
busy = true;
overlay.classList.remove('hidden');
refreshStatus();
try {
const request = JSON.stringify({name, brief, fields});
window.pyodide.globals.set('user_query', request);
const response = await window.pyodide.runPythonAsync('await process_user_query(user_query)');
fullResult = String(response ?? '').trim();
if (!fullResult) throw new Error('El generador no devolvió archivos. Prueba con una descripción más concreta.');
files = parseFiles(fullResult);
select.replaceChildren();
select.add(new Option('Resultado completo', 'full'));
for (const filename of ['index.html', 'app.php', 'schema.sql']) {
if (files[filename]) select.add(new Option(filename, filename));
}
if (Object.keys(files).length < 3) showError('No se pudieron identificar los tres archivos por separado. Puedes revisar y descargar el resultado completo.');
render();
} catch (cause) {
showError('No se pudo crear el proyecto: ' + (cause && cause.message ? cause.message : String(cause)));
} finally {
busy = false;
overlay.classList.add('hidden');
refreshStatus();
}
});
reset.addEventListener('click', () => {
form.reset();
fullResult = '';
files = {};
select.replaceChildren(new Option('Resultado completo', 'full'));
clearError();
render();
el('project-name').focus();
});
select.addEventListener('change', render);
downloadFile.addEventListener('click', () => {
if (!fullResult) return;
const selected = select.value;
if (selected === 'full') save('proyecto-completo.txt', fullResult + setupGuide(), 'text/plain;charset=utf-8');
else if (files[selected]) save(selected, files[selected] + '\n', selected.endsWith('.html') ? 'text/html;charset=utf-8' : 'text/plain;charset=utf-8');
});
downloadAll.addEventListener('click', () => {
if (fullResult) save('proyecto-completo.txt', fullResult + setupGuide(), 'text/plain;charset=utf-8');
});
document.addEventListener('pyodide-ready', () => { ready = true; refreshStatus(); });
if (window.pyodideReady) ready = true;
refreshStatus();
})();
import json
async def process_user_query(query: str) -> str:
"""Generate HTML, PHP, and SQLite project files from a project brief.
Args:
query: JSON containing the project name, brief, and optional data fields.
Returns:
The generated files, separated by filename markers.
"""
try:
data = json.loads(query)
except (ValueError, TypeError):
return "No se pudo interpretar el proyecto. Completa el formulario e inténtalo de nuevo."
if not isinstance(data, dict):
return "Los datos del proyecto no tienen el formato esperado."
name = str(data.get("name", "")).strip()[:80]
brief = str(data.get("brief", "")).strip()[:4500]
fields = str(data.get("fields", "")).strip()[:1200]
if not name or not brief:
return "Escribe un nombre y una descripción para crear el proyecto."
prompt = (
"Crea una aplicación web inicial PEQUEÑA y funcional, en español.\n"
f"Nombre: {name}\nObjetivo: {brief}\nCampos deseados: {fields or 'elige los mínimos necesarios'}\n\n"
"Devuelve EXACTAMENTE tres secciones con estos encabezados en líneas independientes:\n"
"=== index.html ===\n```html\n[código completo]\n```\n"
"=== app.php ===\n```php\n[código completo]\n```\n"
"=== schema.sql ===\n```sql\n[código completo]\n```\n"
"Sin explicaciones fuera de las tres secciones. No omitas código ni uses puntos suspensivos. "
"index.html debe llamar con fetch('app.php') a una API JSON, mostrar listas y errores, "
"y escapar el texto de usuarios al insertarlo en HTML (o usar textContent). "
"app.php debe usar PDO_SQLITE y sentencias preparadas para datos del usuario, implementar "
"como mínimo crear y listar registros, validar entradas y devolver JSON y códigos HTTP. "
"Debe crear automáticamente una base SQLite en una carpeta privada fuera del directorio público "
"(por ejemplo dirname(__DIR__) . '/private'), crear la carpeta si falta, y ejecutar al inicio "
"un CREATE TABLE IF NOT EXISTS equivalente al de schema.sql; admitir SQLITE_PATH como ruta "
"alternativa mediante getenv. No concatenes valores de usuario en SQL. "
"El HTML y PHP deben concordar en nombres de campos, rutas y formato de respuesta. "
"No dependas de frameworks, CDNs ni archivos adicionales. Mantén el proyecto breve y ejecutable "
"con php -S localhost:8000 desde la carpeta pública, y con extensiones PDO_SQLITE habilitadas."
)
return str(await agentop_llm.generate(prompt[:7400], globals().get("TEMPLATE_SYSTEM_PROMPT", "")))
Name your agent
Based on . You'll get your own private copy to try and customize.