EmDash para desarrolladores de WordPress

En esta página

EmDash lleva conceptos familiares de WordPress—entradas, páginas, taxonomías, menús, widgets y una biblioteca de medios—a un stack moderno con Astro. Tu conocimiento de gestión de contenidos se transfiere directamente.

Lo que sigue siendo familiar

Los conceptos que conoces de WordPress son funciones de primera clase en EmDash:

  • Collections funcionan como Custom Post Types—define la estructura del contenido y consúltala en las plantillas
  • Taxonomies igual—jerárquicas (como categorías) y planas (como etiquetas)
  • Menus con orden por arrastrar y soltar y elementos anidados
  • Widget Areas para barras laterales y regiones de contenido dinámico
  • Media library con subida, organización y gestión de imágenes
  • Admin UI que los editores pueden usar sin tocar código

Qué cambia

La implementación cambia, pero el modelo mental se mantiene:

TypeScript en lugar de PHP

Las plantillas son componentes Astro. La sintaxis es más limpia, pero el concepto es el mismo: código en el servidor que genera HTML.

Content APIs en lugar de WP_Query

Funciones de consulta como getEmDashCollection() sustituyen a WP_Query. Sin SQL, solo llamadas a funciones.

Enrutado basado en archivos

Los archivos en src/pages/ se convierten en URLs. Sin reglas de reescritura ni jerarquía de plantillas que memorizar.

Componentes en lugar de partes de plantilla

Importa y usa componentes. Misma idea que get_template_part(), mejor organización.

Referencia rápida

WordPressEmDashNotas
Custom Post TypesCollectionsDefinir vía admin UI o API
WP_QuerygetEmDashCollection()Filtros, límites, consultas por taxonomía
get_post()getEmDashEntry()Devuelve entrada o null
Categories/TagsTaxonomiesSe mantiene el soporte jerárquico
register_nav_menus()getMenu()Menús de primera clase
register_sidebar()getWidgetArea()Áreas de widgets de primera clase
bloginfo('name')getSiteSetting("title")API de ajustes del sitio
the_content()<PortableText />Renderizado de contenido estructurado
ShortcodesPortable Text blocksComponentes personalizados
add_action/filter()Plugin hookscontent:beforeSave, etc.
wp_optionsctx.kvAlmacenamiento clave-valor
Theme directorysrc/ directoryComponentes, layouts, páginas
functions.phpastro.config.mjs + EmDash configConfiguración de build y tiempo de ejecución

Content APIs

Consultar collections

Las consultas en WordPress usan WP_Query o funciones auxiliares. EmDash usa funciones de consulta tipadas.

WordPress

<?php
$posts = new WP_Query([
  'post_type' => 'post',
  'posts_per_page' => 10,
  'post_status' => 'publish',
  'category_name' => 'news',
]);

while ($posts->have_posts()) :
$posts->the_post();
?>

  <h2><?php the_title(); ?></h2>
  <?php the_excerpt(); ?>
<?php endwhile; ?>

EmDash

---
import { getEmDashCollection } from "emdash";

const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
limit: 10,
where: { category: "news" },
});

---

{posts.map((post) => (

  <article>
    <h2>{post.data.title}</h2>
    <p>{post.data.excerpt}</p>
  </article>
))}

Obtener una sola entrada

WordPress

<?php
$post = get_post($id);
?>
<article>
  <h1><?php echo $post->post_title; ?></h1>
  <?php echo apply_filters('the_content', $post->post_content); ?>
</article>

EmDash

---
import { getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";

const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);

## if (!post) return Astro.redirect("/404");

<article>
  <h1>{post.data.title}</h1>
  <PortableText value={post.data.content} />
</article>

Jerarquía de plantillas

WordPress usa una jerarquía de plantillas para elegir qué archivo renderiza una página. Astro usa enrutado explícito basado en archivos.

WordPress TemplateEquivalente en EmDash
index.phpsrc/pages/index.astro
single.phpsrc/pages/posts/[slug].astro
single-{type}.phpsrc/pages/{type}/[slug].astro
page.phpsrc/pages/pages/[slug].astro
archive.phpsrc/pages/posts/index.astro
archive-{type}.phpsrc/pages/{type}/index.astro
category.phpsrc/pages/categories/[slug].astro
tag.phpsrc/pages/tags/[slug].astro
search.phpsrc/pages/search.astro
404.phpsrc/pages/404.astro
header.php / footer.phpsrc/layouts/Base.astro
sidebar.phpsrc/components/Sidebar.astro

Template parts → Componentes

Las partes de plantilla de WordPress se convierten en componentes Astro:

WordPress

// In template:
get_template_part('template-parts/content', 'post');

// template-parts/content-post.php:

<article class="post">
  <h2><?php the_title(); ?></h2>
  <?php the_excerpt(); ?>
</article>

EmDash

---
const { post } = Astro.props;
---

<article class="post">
	<h2>{post.data.title}</h2>
	<p>{post.data.excerpt}</p>
</article>
---
import PostCard from "../components/PostCard.astro";
import { getEmDashCollection } from "emdash";

const { entries: posts } = await getEmDashCollection("posts");
---

{posts.map((post) => <PostCard {post} />)}

Menús

EmDash ofrece menús de primera clase con resolución automática de URL:

WordPress

<?php
wp_nav_menu([
  'theme_location' => 'primary',
  'container' => 'nav',
]);
?>

EmDash

---
import { getMenu } from "emdash";

## const menu = await getMenu("primary");

<nav>
  <ul>
    {menu?.items.map((item) => (
      <li>
        <a href={item.url}>{item.label}</a>
      </li>
    ))}
  </ul>
</nav>

Los menús se crean desde la admin UI, archivos seed o importación de WordPress.

Áreas de widgets

Las áreas de widgets funcionan como barras laterales en WordPress:

WordPress

<?php if (is_active_sidebar('sidebar-1')) : ?>
  <aside>
    <?php dynamic_sidebar('sidebar-1'); ?>
  </aside>
<?php endif; ?>

EmDash

---
import { getWidgetArea } from "emdash";
import { PortableText } from "emdash/ui";

## const sidebar = await getWidgetArea("sidebar");

{sidebar && (

  <aside>
    {sidebar.widgets.map((widget) => {
      if (widget.type === "content") {
        return <PortableText value={widget.content} />;
      }
      // Handle other widget types
    })}
  </aside>
)}

Ajustes del sitio

Las opciones del sitio y del personalizador se mapean a getSiteSetting():

WordPressEmDash
bloginfo('name')getSiteSetting("title")
bloginfo('description')getSiteSetting("tagline")
get_custom_logo()getSiteSetting("logo")
get_option('date_format')getSiteSetting("dateFormat")
home_url()Astro.site
import { getSiteSetting } from "emdash";

const title = await getSiteSetting("title");
const logo = await getSiteSetting("logo"); // Returns { mediaId, alt, url }

Taxonomías

Las taxonomías son conceptualmente iguales—jerárquicas (como categorías) o planas (como etiquetas):

import { getTaxonomyTerms, getEntryTerms, getTerm } from "emdash";

// Get all categories
const categories = await getTaxonomyTerms("categories");

// Get a specific term
const news = await getTerm("categories", "news");

// Get terms for a post
const postCategories = await getEntryTerms("posts", postId, "categories");

Hooks → Sistema de plugins

Los hooks de WordPress (add_action, add_filter) pasan a ser hooks de plugins de EmDash:

WordPress HookEmDash HookPropósito
save_postcontent:beforeSaveModificar contenido antes de guardar
the_contentPortableText componentsTransformar el contenido renderizado
pre_get_postsQuery optionsFiltrar consultas
wp_headLayout <head>Añadir contenido en el head
wp_footerLayout before </body>Añadir contenido en el footer

Qué mejora en EmDash

Seguridad de tipos

TypeScript en todo el proyecto. Collections, consultas y componentes totalmente tipados. Se acabó adivinar nombres de campos o tipos de retorno.

Rendimiento

Sin sobrecarga de PHP. Generación estática por defecto. Render en servidor cuando hace falta. Listo para despliegue en edge.

DX moderna

Hot module replacement. Arquitectura basada en componentes. Herramientas actuales (Vite, TypeScript, ESLint).

Despliegues basados en Git

Código y plantillas en git. Contenido en la base de datos. Sin FTP, sin permisos de archivos, sin sitios hackeados.

Enlaces de vista previa

EmDash genera URL de vista previa seguras con tokens firmados HMAC. Los editores pueden previsualizar borradores sin iniciar sesión en producción—comparten un enlace, no credenciales.

Sin conflictos entre plugins

Desaparecen los conflictos típicos de plugins en WordPress. Los plugins de EmDash se ejecutan en contextos aislados con APIs explícitas. Sin contaminación de estado global.

Experiencia del editor de contenido

Los editores usan el panel de administración de EmDash, similar a wp-admin:

  • Dashboard con actividad reciente
  • Listados de collections con búsqueda, filtros y acciones masivas
  • Editor enriquecido para contenido (Portable Text, no Gutenberg)
  • Biblioteca de medios con subida por arrastrar y soltar
  • Constructor de menús con orden por arrastrar y soltar
  • Editor de áreas de widgets para contenido en la barra lateral

La experiencia de edición es familiar. La tecnología debajo es moderna.

Ruta de migración

EmDash importa contenido de WordPress directamente:

  1. Exportar desde WordPress (Herramientas → Exportar)
  2. Subir el archivo .xml en el admin de EmDash
  3. Mapear tipos de entrada a collections
  4. Importar contenido y medios

Se transfieren entradas, páginas, taxonomías, menús y medios. Los bloques de Gutenberg se convierten a Portable Text. Los campos personalizados se analizan y mapean.

Consulta la guía de migración desde WordPress para instrucciones completas.

Próximos pasos