Astro per sviluppatori WordPress

In questa pagina

Astro è un framework web per la creazione di siti web orientati ai contenuti. Quando si utilizza EmDash, Astro sostituisce il tuo tema WordPress: gestisce il templating, il routing e il rendering.

Questa guida insegna i fondamenti di Astro mappandoli sui concetti WordPress che già comprendi.

Cambiamenti di paradigma chiave

Renderizzato lato server per impostazione predefinita

Come PHP, il codice Astro viene eseguito sul server. A differenza di PHP, genera HTML statico per impostazione predefinita con zero JavaScript.

Zero JS a meno che non lo aggiungi

WordPress carica jQuery e gli script del tema automaticamente. Astro non invia nulla al browser a meno che non lo aggiungi esplicitamente.

Architettura basata su componenti

Invece di tag di template sparsi e include, costruisci con componenti componibili e autonomi.

Routing basato su file

Nessuna regola di riscrittura o query_vars. La struttura dei file in src/pages/ definisce i tuoi URL direttamente.

Struttura del progetto

I temi WordPress hanno una struttura piatta con nomi di file magici. Astro utilizza directory esplicite:

WordPressAstroScopo
index.php, single.phpsrc/pages/Routes (URLs)
template-parts/src/components/Pezzi di UI riutilizzabili
header.php + footer.phpsrc/layouts/Wrapper di pagina
style.csssrc/styles/CSS globale
functions.phpastro.config.mjsConfigurazione del sito

L’albero seguente mostra un layout tipico di progetto Astro:

src/
├── components/        # Reusable UI (Header, PostCard, etc.)
├── layouts/           # Page shells (Base.astro)
├── pages/             # Routes - files become URLs
│   ├── index.astro    # → /
│   ├── posts/
│   │   ├── index.astro      # → /posts
│   │   └── [slug].astro     # → /posts/hello-world
│   └── [slug].astro   # → /about, /contact, etc.
└── styles/
    └── global.css

Componenti Astro

I file .astro sono l’equivalente Astro dei template PHP. Ogni file ha due parti:

  1. Frontmatter (tra i delimitatori ---) — Codice lato server, come PHP all’inizio di un template
  2. Template — HTML con espressioni, come il resto di un template PHP

Il seguente componente dichiara props tipizzate nel frontmatter e le renderizza nel template:

---
// Frontmatter: runs on server, never sent to browser
interface Props {
  title: string;
  excerpt: string;
  url: string;
}

const { title, excerpt, url } = Astro.props;
---
<!-- Template: outputs HTML -->
<article class="post-card">
  <h2><a href={url}>{title}</a></h2>
  <p>{excerpt}</p>
</article>

Differenze chiave da PHP:

  • Il frontmatter è isolato. Le variabili dichiarate lì sono disponibili nel template, ma il codice stesso non raggiunge mai il browser.
  • Gli import vanno nel frontmatter. Componenti, dati, utility: tutto viene importato in alto.
  • TypeScript funziona. Definisci i tipi di props con interface Props per l’autocompletamento dell’editor e la validazione.

Espressioni di template

I template Astro usano {parentesi graffe} invece dei tag <?php ?>. La sintassi è simile a JSX ma genera HTML puro.

Astro

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

const { entries: posts } = await getEmDashCollection("posts");
const showTitle = true;
---
{showTitle && <h1>Latest Posts</h1>}

{posts.length > 0 ? (
  <ul>
    {posts.map(post => (
      <li>
        <a href={`/posts/${post.id}`}>{post.data.title}</a>
      </li>
    ))}
  </ul>
) : (
  <p>No posts found.</p>
)}

PHP

<?php
$posts = new WP_Query(['post_type' => 'post']);
$show_title = true;
?>

<?php if ($show_title): ?>
  <h1>Latest Posts</h1>
<?php endif; ?>

<?php if ($posts->have_posts()): ?>
  <ul>
    <?php while ($posts->have_posts()): $posts->the_post(); ?>
      <li>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
      </li>
    <?php endwhile; wp_reset_postdata(); ?>
  </ul>
<?php else: ?>
  <p>No posts found.</p>
<?php endif; ?>

Pattern di espressione

PatternScopo
{variable}Mostra un valore
{condition && <Element />}Rendering condizionale
{condition ? <A /> : <B />}If/else
{items.map(item => <Li>{item}</Li>)}Loop

Props e Slots

I componenti ricevono dati tramite props (come argomenti di funzione) e slots (come punti di inserimento do_action).

Astro

---
interface Props {
  title: string;
  featured?: boolean;
}

const { title, featured = false } = Astro.props;
---
<article class:list={["card", { featured }]}>
  <h2>{title}</h2>
  <slot />
  <slot name="footer" />
</article>

Il seguente markup utilizza quel componente, passando lo slot predefinito e uno slot footer nominato:

<Card title="Hello" featured>
  <p>This goes in the default slot.</p>
  <footer slot="footer">Footer content</footer>
</Card>

PHP

<?php
// Usage: get_template_part('template-parts/card', null, [
//   'title' => 'Hello',
//   'featured' => true
// ]);

$title = $args['title'] ?? '';
$featured = $args['featured'] ?? false;
$class = $featured ? 'card featured' : 'card';
?>
<article class="<?php echo esc_attr($class); ?>">
  <h2><?php echo esc_html($title); ?></h2>
  <?php
  // No direct equivalent to slots.
  // WordPress uses do_action() for similar patterns:
  do_action('card_content');
  do_action('card_footer');
  ?>
</article>

Props vs $args

In WordPress, get_template_part() passa i dati tramite l’array $args. Le props Astro sono tipizzate e destrutturate:

---
// Type-safe with defaults
interface Props {
  title: string;
  count?: number;
}
const { title, count = 10 } = Astro.props;
---

Slots vs Hooks

WordPress utilizza do_action() per creare punti di inserimento. Astro utilizza gli slot:

WordPressAstro
do_action('before_content')<slot name="before" />
Area contenuti predefinita<slot />
do_action('after_content')<slot name="after" />

La differenza: gli slot ricevono elementi figli nel sito di chiamata, mentre gli hook di WordPress richiedono chiamate add_action() separate altrove.

Layout

I layout avvolgono le pagine con una struttura HTML comune: il <head>, header, footer e tutto ciò che è condiviso tra le pagine. Questo sostituisce header.php + footer.php. Il seguente layout definisce quella shell condivisa ed espone uno slot per il contenuto della pagina:

---
import "../styles/global.css";

interface Props {
  title: string;
  description?: string;
}

const { title, description = "My EmDash Site" } = Astro.props;
---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content={description} />
    <title>{title}</title>
  </head>
  <body>
    <header>
      <nav><!-- Navigation --></nav>
    </header>

    <main>
      <slot />
    </main>

    <footer>
      <p>&copy; {new Date().getFullYear()}</p>
    </footer>
  </body>
</html>

Utilizza il layout in una pagina:

---
import Base from "../layouts/Base.astro";
---
<Base title="Home">
  <h1>Welcome</h1>
  <p>Page content goes in the slot.</p>
</Base>

Stili

Astro offre diversi approcci di stilizzazione. Il più distintivo sono gli stili con ambito.

Stili con ambito

Gli stili in un tag <style> sono automaticamente limitati a quel componente:

<article class="card">
  <h2>Title</h2>
</article>

<style>
  /* Only affects .card in THIS component */
  .card {
    padding: 1rem;
    border: 1px solid #ddd;
  }

  h2 {
    color: navy;
  }
</style>

L’HTML generato include nomi di classe univoci per prevenire la fuoriuscita di stili, in modo che gli stili dei componenti rimangano contenuti senza aumentare la specificità del selettore.

Stili globali

Per stili a livello di sito, crea un file CSS e importalo in un layout:

---
import "../styles/global.css";
---

Classi condizionali

La direttiva class:list sostituisce la costruzione manuale di stringhe di classe:

Astro

---
const { featured, size = "medium" } = Astro.props;
---
<article class:list={[
  "card",
  size,
  { featured, "has-border": true }
]}>

Output: <article class="card medium featured has-border">

PHP

<?php
$classes = ['card', $size];
if ($featured) $classes[] = 'featured';
if (true) $classes[] = 'has-border';
?>
<article class="<?php echo esc_attr(implode(' ', $classes)); ?>">

JavaScript lato client

Astro invia zero JavaScript per impostazione predefinita. Questo è il più grande cambiamento mentale da WordPress.

Aggiungere interattività

Per interazioni semplici, aggiungi un tag <script>:

<button id="menu-toggle">Menu</button>
<nav id="mobile-menu" hidden>
  <slot />
</nav>

<script>
  const toggle = document.getElementById("menu-toggle");
  const menu = document.getElementById("mobile-menu");

  toggle?.addEventListener("click", () => {
    menu?.toggleAttribute("hidden");
  });
</script>

Gli script vengono automaticamente raggruppati e deduplicati. Se questo componente appare due volte su una pagina, lo script viene eseguito una volta.

Componenti interattivi avanzati

Per un’interattività più complessa, Astro può caricare componenti JavaScript (React, Vue, Svelte) su richiesta. Questo è opzionale: la maggior parte dei siti funziona bene con solo tag <script>. La seguente pagina carica un componente solo quando scorre nella vista:

---
import SearchWidget from "../components/SearchWidget.jsx";
---
<!-- Only load JavaScript when the search box scrolls into view -->
<SearchWidget client:visible />
DirettivaQuando si carica JavaScript
client:loadImmediatamente al caricamento della pagina
client:visibleQuando il componente entra nel viewport
client:idleQuando il browser è inattivo

Routing

Astro utilizza il routing basato su file. I file in src/pages/ diventano URL:

FileURL
src/pages/index.astro/
src/pages/about.astro/about
src/pages/posts/index.astro/posts
src/pages/posts/[slug].astro/posts/hello-world
src/pages/[...slug].astroQualsiasi percorso (catch-all)

Route dinamiche

Per contenuti CMS, utilizza la sintassi con parentesi per segmenti dinamici:

---
import { getEmDashCollection, getEmDashEntry } from "emdash";
import Base from "../../layouts/Base.astro";
import { PortableText } from "emdash/ui";

// For static builds, define which pages to generate
export async function getStaticPaths() {
  const { entries: posts } = await getEmDashCollection("posts");
  return posts.map(post => ({
    params: { slug: post.id },
    props: { post },
  }));
}

const { post } = Astro.props;
---
<Base title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <PortableText value={post.data.content} />
  </article>
</Base>

Confronto con WordPress

WordPressAstro
Gerarchia di template (single-post.php)File esplicito: posts/[slug].astro
Regole di riscrittura + query_varsStruttura dei file
$wp_query determina il templateURL mappa direttamente al file
add_rewrite_rule()Creare file o cartelle

Dove vivono i concetti WordPress

Un riferimento per trovare l’equivalente Astro/EmDash delle funzionalità WordPress:

Templating

WordPressAstro/EmDash
Gerarchia di templateRouting basato su file in src/pages/
get_template_part()Importare e utilizzare componenti
the_content()<PortableText value={content} />
the_title(), the_*()Accesso tramite post.data.title
Tag di templateEspressioni di template {value}
body_class()Direttiva class:list

Dati e query

WordPressAstro/EmDash
WP_QuerygetEmDashCollection(type, filters)
get_post()getEmDashEntry(type, id)
get_posts()getEmDashCollection(type)
get_the_terms()Accesso tramite entry.data.categories
get_post_meta()Accesso tramite entry.data.fieldName
get_option()getSiteSettings()
wp_nav_menu()getMenu(location)

Estensibilità

WordPressAstro/EmDash
add_action()Hook EmDash, middleware Astro
add_filter()Hook EmDash
add_shortcode()Blocchi personalizzati Portable Text
register_block_type()Blocchi personalizzati Portable Text
register_sidebar()Aree widget EmDash
PluginIntegrazioni Astro + plugin EmDash

Tipi di contenuto

WordPressAstro/EmDash
register_post_type()Creare collezione nell’UI admin
register_taxonomy()Creare tassonomia nell’UI admin
register_meta()Aggiungere campo allo schema di collezione
Stato postStato voce (draft, published, etc.)
Immagine in evidenzaCampo di riferimento media
Blocchi GutenbergBlocchi Portable Text

Mappatura dei concetti

I principali cambiamenti da WordPress ad Astro trattati in questa guida:

  • I template PHP diventano componenti Astro: codice server più HTML, con organizzazione file esplicita.
  • I tag di template diventano props e import: i dati fluiscono attraverso argomenti invece di globali.
  • I file del tema diventano una directory di pagine: gli URL corrispondono alla struttura dei file.
  • Gli hook diventano slot e middleware: i punti di inserimento sono definiti dove viene passato il contenuto.
  • jQuery si carica per impostazione predefinita in WordPress; Astro non invia JavaScript finché non lo aggiungi.

Inizia con la guida Getting Started per creare il tuo primo sito EmDash, o esplora Working with Content per imparare a interrogare e renderizzare dati CMS.