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
| WordPress | EmDash | Notas |
|---|---|---|
| Custom Post Types | Collections | Defina via UI de admin ou API |
WP_Query | getEmDashCollection() | Filtros, limites, consultas de taxonomia |
get_post() | getEmDashEntry() | Retorna entrada ou null |
| Categorias/Tags | Taxonomias | Suporte 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 |
| Shortcodes | Blocos Portable Text | Componentes personalizados |
add_action/filter() | Hooks de plugin | content:beforeSave, etc. |
wp_options | ctx.kv | Armazenamento chave-valor |
| Diretório de tema | Diretório src/ | Componentes, layouts, páginas |
functions.php | astro.config.mjs + configuração EmDash | Configuraçã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 WordPress | Equivalente EmDash |
|---|---|
index.php | src/pages/index.astro |
single.php | src/pages/posts/[slug].astro |
single-{type}.php | src/pages/{type}/[slug].astro |
page.php | src/pages/pages/[slug].astro |
archive.php | src/pages/posts/index.astro |
archive-{type}.php | src/pages/{type}/index.astro |
category.php | src/pages/categories/[slug].astro |
tag.php | src/pages/tags/[slug].astro |
search.php | src/pages/search.astro |
404.php | src/pages/404.astro |
header.php / footer.php | src/layouts/Base.astro |
sidebar.php | src/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} />)} Menus
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():
| WordPress | EmDash |
|---|---|
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 WordPress | Hook EmDash | Propósito |
|---|---|---|
save_post | content:beforeSave | Modificar conteúdo antes de salvar |
the_content | Componentes PortableText | Transformar conteúdo renderizado |
pre_get_posts | Opções de consulta | Filtrar consultas |
wp_head | Layout <head> | Adicionar conteúdo head |
wp_footer | Layout 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.
Links de preview
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:
- Exportar do WordPress (Ferramentas → Exportar)
- Fazer upload do arquivo
.xmlno admin do EmDash - Mapear post types para collections
- 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
- Começando — Configure seu primeiro site EmDash
- Consultando conteúdo — Mergulho profundo nas APIs de conteúdo
- Taxonomias — Categorias, tags e taxonomias personalizadas
- Menus — Menus de navegação
- Migrar do WordPress — Importar conteúdo existente