EmDash para desenvolvedores WordPress

Nesta página

EmDash traz conceitos familiares do WordPress—posts, páginas, taxonomias, menus, widgets e uma biblioteca de mídia—para um stack Astro moderno. Seu conhecimento de gerenciamento de conteúdo transfere-se diretamente.

O que permanece familiar

Os conceitos que você conhece do WordPress são recursos de primeira classe no EmDash:

  • Collections funcionam como Custom Post Types—defina sua estrutura de conteúdo, consulte-a em templates
  • Taxonomias funcionam da mesma forma—hierárquicas (como categorias) e planas (como tags)
  • Menus com ordenação drag-and-drop e itens aninhados
  • Áreas de widgets para sidebars e regiões de conteúdo dinâmico
  • Biblioteca de mídia com upload, organização e gerenciamento de imagens
  • UI de administração que editores de conteúdo podem usar sem tocar em código

O que é diferente

A implementação muda, mas o modelo mental permanece o mesmo:

TypeScript em vez de PHP

Templates são componentes Astro. A sintaxe é mais limpa, mas o conceito é o mesmo: código de servidor que gera HTML.

APIs de conteúdo em vez de WP_Query

Funções de consulta como getEmDashCollection() substituem WP_Query. Sem SQL, apenas chamadas de função.

Roteamento baseado em arquivos

Arquivos em src/pages/ tornam-se URLs. Sem regras de reescrita ou hierarquia de templates para memorizar.

Componentes em vez de template parts

Importe e use componentes. Mesma ideia que get_template_part(), melhor organização.

Referência rápida

WordPressEmDashNotas
Custom Post TypesCollectionsDefina via UI de admin ou API
WP_QuerygetEmDashCollection()Filtros, limites, consultas de taxonomia
get_post()getEmDashEntry()Retorna entrada ou null
Categorias/TagsTaxonomiasSuporte hierárquico preservado
register_nav_menus()getMenu()Suporte de menu de primeira classe
register_sidebar()getWidgetArea()Áreas de widgets de primeira classe
bloginfo('name')getSiteSetting("title")API de configurações do site
the_content()<PortableText />Renderização de conteúdo estruturado
ShortcodesBlocos Portable TextComponentes personalizados
add_action/filter()Hooks de plugincontent:beforeSave, etc.
wp_optionsctx.kvArmazenamento chave-valor
Diretório de temaDiretório src/Componentes, layouts, páginas
functions.phpastro.config.mjs + configuração EmDashConfiguração de build e runtime

APIs de conteúdo

Consultar Collections

Consultas WordPress usam WP_Query ou funções auxiliares. EmDash usa funções 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>
))}

Obter uma única entrada

Os exemplos a seguir buscam uma entrada por identificador e a renderizam, no WordPress e no EmDash:

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>

Hierarquia de templates

WordPress usa uma hierarquia de templates para selecionar qual arquivo renderiza uma página. Astro usa roteamento explícito baseado em arquivos.

Template WordPressEquivalente 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

Template parts do WordPress tornam-se componentes Astro:

WordPress

// No 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>

A página seguinte importa esse componente e o renderiza para cada post:

---
import PostCard from "../components/PostCard.astro";
import { getEmDashCollection } from "emdash";

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

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

EmDash tem suporte de menu de primeira classe com resolução 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>

Menus são criados via UI de admin, arquivos seed ou importação do WordPress.

Áreas de widgets

Áreas de widgets funcionam como sidebars no 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} />;
      }
      // Tratar outros tipos de widget
    })}
  </aside>
)}

Configurações do site

Opções do site e configurações do customizer mapeiam para 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

O exemplo a seguir lê configurações individuais com getSiteSetting():

import { getSiteSetting } from "emdash";

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

Taxonomias

Taxonomias funcionam da mesma forma conceitualmente—hierárquicas (como categorias) ou planas (como tags):

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

// Obter todas as categorias
const categories = await getTaxonomyTerms("categories");

// Obter um termo específico
const news = await getTerm("categories", "news");

// Obter termos para um post
const postCategories = await getEntryTerms("posts", postId, "categories");

Hooks → Sistema de plugin

Hooks do WordPress (add_action, add_filter) tornam-se hooks de plugin do EmDash:

Hook WordPressHook EmDashPropósito
save_postcontent:beforeSaveModificar conteúdo antes de salvar
the_contentComponentes PortableTextTransformar conteúdo renderizado
pre_get_postsOpções de consultaFiltrar consultas
wp_headLayout <head>Adicionar conteúdo head
wp_footerLayout antes de </body>Adicionar conteúdo footer

O que é melhor no EmDash

Segurança de tipos

TypeScript por toda parte. Collections, consultas e componentes são completamente tipados, então nomes de campo e tipos de retorno são autocompletados e verificados em tempo de build.

Performance

Geração estática por padrão, com renderização de servidor quando necessário. Pronto para deploy em edge.

DX moderna

Hot Module Replacement. Arquitetura baseada em componentes. Ferramentas modernas (Vite, TypeScript, ESLint).

Deploys baseados em Git

Código e templates vivem no git; conteúdo vive no banco de dados. Deploy fazendo push do código.

EmDash gera URLs de preview seguras com tokens assinados HMAC. Editores de conteúdo compartilham um link de preview para mostrar um rascunho, para que revisores possam vê-lo sem login de produção.

Plugins isolados

Plugins EmDash executam em contextos isolados com APIs explícitas. Cada plugin alcança apenas as APIs que declara, então plugins não compartilham ou sobrescrevem o estado global um do outro.

Experiência do editor de conteúdo

Editores de conteúdo usam o painel de admin do EmDash, similar ao wp-admin:

  • Dashboard com atividade recente
  • Listagens de collections com busca, filtros e ações em massa
  • Editor rico para conteúdo (Portable Text, não Gutenberg)
  • Biblioteca de mídia com upload drag-and-drop
  • Construtor de menu com ordenação drag-and-drop
  • Editor de área de widget para conteúdo de sidebar

A experiência de edição é familiar. A tecnologia subjacente é moderna.

Caminho de migração

EmDash importa conteúdo do WordPress diretamente:

  1. Exportar do WordPress (Ferramentas → Exportar)
  2. Fazer upload do arquivo .xml no admin do EmDash
  3. Mapear post types para collections
  4. Importar conteúdo e mídia

Posts, páginas, taxonomias, menus e mídia são transferidos. Blocos Gutenberg são convertidos para Portable Text. Custom fields são analisados e mapeados.

Veja o Guia de migração WordPress para instruções completas.

Próximos passos