🤖 Android TippsBYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen(17.09.2026 um 13:00 Uhr)
🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🕵️ SicherheitslückenCVE-2026-8919 | ASUS GameSDK up to 1.0.5 Web cross-domain policy(17.09.2026 um 13:05 Uhr)
🤖 Android TippsBYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen(17.09.2026 um 13:00 Uhr)
🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🕵️ SicherheitslückenCVE-2026-8919 | ASUS GameSDK up to 1.0.5 Web cross-domain policy(17.09.2026 um 13:05 Uhr)
🔧 Programmierung 🕛 vor 4 Monaten 8 Min Lesezeit
0

Exporting WordPress Content to JSON for Headless and Static Sites

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

You've got years of content in WordPress. Now you want to move to a static site generator, build a headless frontend, or just back up your content in a portable format.



The WordPress REST API exists, but it requires authentication setup, pagination handling, and multiple requests. Sometimes you just want a clean JSON export.



Here's how to build one.






The Export Class






CODE
<?php
/**
* WordPress Content Exporter
*/

class Content_Exporter {

/**
* Export posts based on options
*
* @param array $options Export options
* @return array
*/

public function export( $options = array() ) {
$defaults = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'category' => '',
'include' => array( 'content', 'excerpt', 'featured_image', 'taxonomies', 'meta' ),
);

$options = wp_parse_args( $options, $defaults );

$args = array(
'post_type' => sanitize_key( $options['post_type'] ),
'post_status' => sanitize_key( $options['post_status'] ),
'posts_per_page' => intval( $options['posts_per_page'] ),
'orderby' => 'date',
'order' => 'DESC',
);

// Category filter
if ( ! empty( $options['category'] ) ) {
$args['cat'] = intval( $options['category'] );
}

$query = new WP_Query( $args );
$posts = array();

if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$posts[] = $this->format_post( get_post(), $options['include'] );
}
wp_reset_postdata();
}

return $posts;
}

/**
* Format a single post
*/

private function format_post( $post, $include ) {
$data = array(
'id' => $post->ID,
'title' => $post->post_title,
'slug' => $post->post_name,
'date' => $post->post_date,
'modified' => $post->post_modified,
'status' => $post->post_status,
'type' => $post->post_type,
'url' => get_permalink( $post->ID ),
'author' => $this->get_author( $post->post_author ),
);

if ( in_array( 'content', $include, true ) ) {
$data['content'] = $post->post_content;
$data['content_rendered'] = apply_filters( 'the_content', $post->post_content );
}

if ( in_array( 'excerpt', $include, true ) ) {
$data['excerpt'] = $post->post_excerpt
? $post->post_excerpt
: wp_trim_words( $post->post_content, 55 );
}

if ( in_array( 'featured_image', $include, true ) ) {
$data['featured_image'] = $this->get_featured_image( $post->ID );
}

if ( in_array( 'taxonomies', $include, true ) ) {
$data['taxonomies'] = $this->get_taxonomies( $post->ID, $post->post_type );
}

if ( in_array( 'meta', $include, true ) ) {
$data['meta'] = $this->get_public_meta( $post->ID );
}

return $data;
}

/**
* Get author data
*/

private function get_author( $author_id ) {
$user = get_userdata( $author_id );
if ( ! $user ) {
return null;
}

return array(
'id' => $user->ID,
'name' => $user->display_name,
'slug' => $user->user_nicename,
);
}

/**
* Get featured image
*/

private function get_featured_image( $post_id ) {
$thumbnail_id = get_post_thumbnail_id( $post_id );
if ( ! $thumbnail_id ) {
return null;
}

$image = wp_get_attachment_image_src( $thumbnail_id, 'full' );
$alt = get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true );

return array(
'id' => $thumbnail_id,
'url' => $image ? $image[0] : '',
'width' => $image ? $image[1] : 0,
'height' => $image ? $image[2] : 0,
'alt' => $alt,
);
}

/**
* Get taxonomies
*/

private function get_taxonomies( $post_id, $post_type ) {
$taxonomies = get_object_taxonomies( $post_type, 'objects' );
$data = array();

foreach ( $taxonomies as $taxonomy ) {
$terms = get_the_terms( $post_id, $taxonomy->name );
if ( ! $terms || is_wp_error( $terms ) ) {
continue;
}

$data[ $taxonomy->name ] = array_map( function( $term ) {
return array(
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
);
}, $terms );
}

return $data;
}

/**
* Get public meta (exclude private _ prefixed keys)
*/

private function get_public_meta( $post_id ) {
$meta = get_post_meta( $post_id );
$data = array();

foreach ( $meta as $key => $values ) {
// Skip private meta
if ( strpos( $key, '_' ) === 0 ) {
continue;
}
$data[ $key ] = count( $values ) === 1 ? $values[0] : $values;
}

return $data;
}

/**
* Convert to JSON
*/

public function to_json( $posts ) {
return wp_json_encode(
$posts,
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
);
}
}









Usage






CODE
$exporter = new Content_Exporter();

// Export all posts
$posts = $exporter->export();
$json = $exporter->to_json( $posts );

// Export pages only
$pages = $exporter->export( array(
'post_type' => 'page',
) );

// Export specific category
$tutorials = $exporter->export( array(
'category' => 5, // category ID
) );

// Minimal export (no content, just metadata)
$minimal = $exporter->export( array(
'include' => array( 'excerpt', 'featured_image' ),
) );









Adding an Admin Interface






CODE
/**
* Add export page to admin
*/

function add_export_admin_page() {
add_management_page(
'Export Content',
'Export Content',
'manage_options',
'content-export',
'render_export_page'
);
}
add_action( 'admin_menu', 'add_export_admin_page' );

/**
* Handle export
*/

function render_export_page() {
// Handle form submission
if ( isset( $_POST['export_nonce'] ) &&
wp_verify_nonce( $_POST['export_nonce'], 'content_export' ) ) {

$exporter = new Content_Exporter();

$options = array(
'post_type' => sanitize_key( $_POST['post_type'] ?? 'post' ),
'include' => array_map( 'sanitize_key', $_POST['include'] ?? array() ),
);

$posts = $exporter->export( $options );
$json = $exporter->to_json( $posts );

// Trigger download
header( 'Content-Type: application/json' );
header( 'Content-Disposition: attachment; filename="export-' . date('Y-m-d') . '.json"' );
echo $json;
exit;
}

// Render form
$post_types = get_post_types( array( 'public' => true ), 'objects' );
?>
<div class="wrap">
<h1>Export Content to JSON</h1>

<form method="post">
<?php wp_nonce_field( 'content_export', 'export_nonce' ); ?>

<table class="form-table">
<tr>
<th>Post Type</th>
<td>
<select name="post_type">
<?php foreach ( $post_types as $type ) : ?>
<option value="<?php echo esc_attr( $type->name ); ?>">
<?php echo esc_html( $type->labels->name ); ?>
</option>
<?php endforeach; ?>
</select>
</td>
</tr>
<tr>
<th>Include</th>
<td>
<label><input type="checkbox" name="include[]" value="content" checked> Content</label><br>
<label><input type="checkbox" name="include[]" value="excerpt" checked> Excerpt</label><br>
<label><input type="checkbox" name="include[]" value="featured_image" checked> Featured Image</label><br>
<label><input type="checkbox" name="include[]" value="taxonomies" checked> Taxonomies</label><br>
<label><input type="checkbox" name="include[]" value="meta"> Custom Meta</label>
</td>
</tr>
</table>

<?php submit_button( 'Download JSON' ); ?>
</form>
</div>
<?php
}









Converting to Markdown



For static site generators like Hugo, Jekyll, or Astro, Markdown with frontmatter is often more useful:




CODE
/**
* Convert posts array to Markdown files content
*/

public function to_markdown( $posts ) {
$output = '';

foreach ( $posts as $post ) {
// Frontmatter
$output .= "---\n";
$output .= 'title: "\"' . str_replace( '\"', '\"', $post['title'] ) . \"\"\n\";"
$output .= 'slug: ' . $post['slug'] . "\n";
$output .= 'date: ' . $post['date'] . "\n";

if ( ! empty( $post['author']['name'] ) ) {
$output .= 'author: ' . $post['author']['name'] . "\n";
}

if ( ! empty( $post['featured_image']['url'] ) ) {
$output .= 'featured_image: ' . $post['featured_image']['url'] . "\n";
}

if ( ! empty( $post['taxonomies']['category'] ) ) {
$cats = array_column( $post['taxonomies']['category'], 'name' );
$output .= 'categories: [' . implode( ', ', $cats ) . "]\n";
}

$output .= "---\n\n";

// Content
$output .= '# ' . $post['title'] . "\n\n";

if ( ! empty( $post['content'] ) ) {
$output .= $this->html_to_markdown( $post['content'] );
}

$output .= "\n\n---\n\n";
}

return trim( $output );
}

/**
* Basic HTML to Markdown
*/

private function html_to_markdown( $html ) {
// Remove WordPress block comments
$html = preg_replace( '/<!-- \/?wp:[^>]+ -->/', '', $html );

$replacements = array(
'/<h1[^>]*>(.*?)<\/h1>/i' => "# $1\n\n",
'/<h2[^>]*>(.*?)<\/h2>/i' => "## $1\n\n",
'/<h3[^>]*>(.*?)<\/h3>/i' => "### $1\n\n",
'/<p[^>]*>(.*?)<\/p>/is' => "$1\n\n",
'/<strong>(.*?)<\/strong>/i' => "**$1**",
'/<em>(.*?)<\/em>/i' => "*$1*",
'/<a[^>]+href=["\']([^"\']+)["\'][^>]*>(.*?)<\/a>/i' => "[$2]($1)",
'/<ul[^>]*>(.*?)<\/ul>/is' => "$1\n",
'/<li[^>]*>(.*?)<\/li>/i' => "- $1\n",
'/<code>(.*?)<\/code>/i' => "`$1`",
'/<br\s*\/?>/i' => "\n",
);

foreach ( $replacements as $pattern => $replacement ) {
$html = preg_replace( $pattern, $replacement, $html );
}

return wp_strip_all_tags( $html );
}









Output Example






CODE
{
"id": 123,
"title": "Getting Started with WordPress",
"slug": "getting-started-wordpress",
"date": "2026-04-15 10:30:00",
"modified": "2026-04-18 14:22:00",
"status": "publish",
"type": "post",
"url": "https://example.com/getting-started-wordpress/",
"author": {
"id": 1,
"name": "John Doe",
"slug": "john-doe"
},
"content": "<!-- wp:paragraph -->Raw content here...",
"content_rendered": "<p>Rendered HTML content...</p>",
"excerpt": "A quick introduction to WordPress...",
"featured_image": {
"id": 456,
"url": "https://example.com/wp-content/uploads/image.jpg",
"width": 1200,
"height": 630,
"alt": "WordPress dashboard"
},
"taxonomies": {
"category": [
{ "id": 1, "name": "Tutorials", "slug": "tutorials" }
],
"post_tag": [
{ "id": 5, "name": "WordPress", "slug": "wordpress" }
]
}
}









Use Cases





  • Migrating to Gatsby/Next.js export, transform, import


  • Backup portable content outside the database


  • Headless WordPress pre-generate JSON for frontend consumption


  • Static site migration export to Markdown for Hugo/Jekyll


  • Content analysis process exported JSON with external tools






ACF Support



If you use Advanced Custom Fields, add this method:




CODE
/**
* Get ACF fields
*/

private function get_acf_fields( $post_id ) {
if ( ! function_exists( 'get_fields' ) ) {
return array();
}

$fields = get_fields( $post_id );
return $fields ? $fields : array();
}






Then add 'acf' to the include array option.






If you need a ready-to-use solution with admin UI, date filtering, and format options, I built

  • More WordPress tools

  • Vollständiger Original-Artikel
    Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
    ↗ Original-Artikel auf dev.to lesen
    Wie bewertest du diesen Beitrag?
    1 Klick Feedback
    Teilen mit Netzwerk & Team:

    Community-Analysen & Experten-Meinungen 0

    Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
    Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
    Community Pulse: Relevanz-Einschätzung
    1 Klick Experten-Votum
    🔴 Akute Relevanz 0%
    🟡 In Evaluierung 0%
    🟢 Keine Auswirkung 0%
    Spannende Innovation 0%
    Verwandte Story-Cluster & Quellen (Vektor-KI)
    Port 8095 Engine
    1 Quelle
    Mercedes bringt eine günstigere C-Klasse Electric mit Allradantrieb auf den Markt
    1 Quelle
    Android 17: Diese Samsung-Galaxy-Smartphones bekommen jetzt das Update
    1 Quelle
    BYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen
    Ähnliche Beiträge
    🔍 Verwandte News

    Auch interessante Nachrichten Exporting WordPress Content to JSON for Headless and Static Sites

    Thematisch verwandte Begriffe: Exporting, WordPress, Content, JSON · 6 Treffer

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...