Por qué mi blog no tiene panel de admin — y no lo necesita
Cuando construí mi landing page con blog, la primera pregunta obvia fue: ¿qué CMS uso? ¿WordPress? ¿Filament? ¿Un panel admin custom en Laravel?
No usé ninguno. Mis posts son archivos Markdown que viven en el repositorio. No hay formularios, no hay WYSIWYG, no hay login de administrador. Y después de varios posts publicados, estoy convencido de que para un blog de desarrollador es la mejor decisión que pude tomar.
El enfoque: Markdown + JSON + Git
La estructura es simple. Cada post es una carpeta dentro de database/seeders/posts/:
database/seeders/posts/
├── mi_primer_post/
│ ├── meta.json
│ ├── es.md
│ └── en.md
├── segundo_post/
│ ├── meta.json
│ ├── es.md
│ └── en.md
El meta.json contiene los metadatos: slugs, títulos, excerpts, categoría, tags y fecha de publicación. Los archivos .md contienen el contenido en cada idioma.
{
"published_at": "2026-03-04",
"slug": {
"es": "mi-post-en-español",
"en": "my-post-in-english"
},
"title": {
"es": "Título en español",
"en": "Title in English"
},
"excerpt": {
"es": "Resumen corto...",
"en": "Short summary..."
},
"category": "arquitectura",
"tags": ["laravel", "markdown"]
}
Un comando artisan sincroniza todo a la base de datos:
php artisan blog:sync
Lee las carpetas, crea o actualiza los posts en la BD, sincroniza categorías y tags. Eso es todo.
Por qué funciona mejor que un panel admin
Versionado real. Cada cambio en un post es un commit de Git. Puedo ver el historial completo de ediciones, hacer rollback a cualquier versión anterior, y tengo backup automático en el remoto. Un panel admin con base de datos no te da eso sin configuración extra.
Escribo en mi editor. VS Code con preview de Markdown, syntax highlighting, copilot para autocompletar. Ningún textarea de un panel admin se acerca a la experiencia de escribir en un editor de código real.
Bilingüe por diseño. Cada post tiene es.md y en.md en la misma carpeta. La relación entre traducciones es implícita por la estructura de archivos. No necesito campos de "idioma" ni selectores de "traducción de" en un formulario.
Cero superficie de ataque. No hay /admin, no hay login, no hay formularios públicos. Nada que proteger. Nada que un bot pueda atacar.
Deploy = publicar. Escribo el post, hago commit, push, y el CI/CD se encarga del resto. El flujo es idéntico al de cualquier feature de código.
El problema que tuve que resolver: las fechas
Mi primer approach tenía un bug sutil. Tanto el seeder como el comando de sync usaban now() para el campo published_at:
'published_at' => now(),
Esto significaba que cada vez que sincronizaba los posts — por ejemplo, después de agregar uno nuevo — todos los posts existentes se actualizaban con la fecha actual. En el blog, todos los artículos aparecían como publicados hoy.
La solución fue mover la fecha de publicación al meta.json:
{
"published_at": "2026-03-04",
...
}
Y en el comando de sync, respetar la fecha existente si el post ya está en la base de datos:
$attributes = [
'title' => $meta['title'][$lang],
'excerpt' => $meta['excerpt'][$lang],
'content' => $content,
'status' => 'published',
'category_id' => $category->id,
'translation_key' => $folderName,
];
$existing = Post::where('slug', $slug)->where('lang', $lang)->first();
if (!$existing) {
$attributes['published_at'] = $meta['published_at'] ?? now();
}
$post = Post::updateOrCreate(
['slug' => $slug, 'lang' => $lang],
$attributes
);
Si el post es nuevo, toma la fecha del meta.json (o now() como fallback). Si ya existe, no toca su published_at. Simple.
El flujo completo para publicar un post
1. Crear carpeta en database/seeders/posts/mi-nuevo-post/
2. Escribir meta.json con metadatos
3. Escribir es.md y en.md con el contenido
4. php artisan blog:sync (para verificar localmente)
5. git add + commit + push
6. Deploy automático
No hay nada que aprender fuera de lo que ya sabes como desarrollador. Es Git. Es Markdown. Es un comando artisan.
¿Cuándo sí necesitarías un panel admin?
Este enfoque tiene límites claros:
- Si alguien no-técnico va a publicar contenido. Un editor de marketing no va a hacer git push.
- Si necesitas publicación programada. Puedes implementarlo, pero un CMS lo trae de caja.
- Si vas a publicar diariamente. A partir de cierto volumen, la fricción de crear carpetas y archivos se acumula.
Para un blog personal de un desarrollador que publica un par de veces al mes, es perfecto. Tienes control total, cero dependencias extra, y tu contenido vive donde debería vivir: en el repositorio.
La conclusión
No todo necesita un panel admin. A veces la solución más simple — archivos en un repositorio — es también la más robusta. Tienes versionado gratis, backups gratis, y un flujo de publicación que ya conoces de memoria.
Si eres desarrollador y estás pensando en montar un blog, considera esto antes de instalar un CMS. Puede que no lo necesites.
Soy Rubén Rangel, Senior Full-Stack Developer con más de 17 años de experiencia construyendo aplicaciones web en producción. Actualmente en Ansira, trabajo en una plataforma SaaS de marketing automation que sirve a más de 100 marcas. Integro IA en mi flujo de trabajo para construir más rápido, más inteligente y con mayor calidad. Disponible para oportunidades full-time y contratos.