API Configuration & Data Fetching
Tags: astro, wordpress, jamstack, tutorial
Published: 2024-02-21 14:54:00

Following my initial discussion, this chapter delves into employing WordPress as a headless CMS for Astro, focusing on Advanced Custom Fields for content structuring. Initially straightforward, the challenge lies in bridging WordPress with Astro.

My development environment, a mirrored structure of WordPress themes synced via rsync across staging and production, emphasizes developer-centric workflow. By localizing changes to the theme folder, it enhances developer experience and simplifies WordPress use for non-developers. Fields managed through PHP in the theme folder ensure version control and clarity.

## Essential Theme Files Overview

Organized as follows, the theme structure facilitates efficient management:

```plaintext
wp-content/themes/wp-rest
├── api/
│   ├── endpoints/
│   │   └── get_menu.php
│   └── endpoint-registration.php
├── blocks/
│   ├── textbox/
│   │   ├── acf.php
│   │   ├── block.json
│   │   └── preview.php
│   └── block-registration.php
├── config/
│   ├── block-access.php
│   ├── menus.php
│   └── setup.php
└── functions.php
```

### `functions.php` Core Functionality

Central to theme operation, this file orchestrates the loading of various scripts.

```php
// Include configuration files
require get_template_directory() . '/config/setup.php';
require get_template_directory() . '/config/block-access.php';
require get_template_directory() . '/config/menus.php';

// Include API endpoints and block methods
require get_template_directory() . '/api/endpoint-registration.php';
require get_template_directory() . '/blocks/block-registration.php';
```

### Theme Setup in `setup.php`

Adjusts WordPress features to match project needs.

```php
function wp_rest_setup() {
    remove_theme_support('core-block-patterns');
    add_theme_support('align-wide');
}
add_action('after_setup_theme', 'wp_rest_setup');
```

### Block Access Management in `block-access.php`

Specifies block access based on user roles, enhancing content customization.

```php
function wp_rest_define_block_groups() {
    $common_blocks = ['core/image', 'core/group', 'core/columns', 'acf/textbox'];
    $editor_blocks = array_merge($common_blocks, ['core/gallery']);
    $admin_blocks = array_merge($editor_blocks, ['core/code', 'core/html']);

    return ['administrator' => $admin_blocks, 'editor' => $editor_blocks, 'default' => $common_blocks];
}

function wp_rest_assign_block_groups($allowed_blocks, $post) {
    $block_groups = wp_rest_define_block_groups();
    $current_user = wp_get_current_user();

    return $block_groups[in_array('administrator', $current_user->roles) ? 'administrator' : (in_array('editor', $current_user->roles) ? 'editor' : 'default')];
}
add_filter('allowed_block_types_all', 'wp_rest_assign_block_groups', 10, 2);
```

### Menu Configuration in `menus.php`

Registers menus within the theme for controlled navigation management.

```php
function wp_rest_register_menus() {
    register_nav_menus([
        'overlay_menu' => esc_html__('Main Navigation', 'wp-rest'),
        'header_submenu' => esc_html__('Sub Navigation', 'wp-rest'),
        'footer_menu' => esc_html__('Footer Navigation', 'wp-rest'),
        'footer_submenu' => esc_html__('Footer Sub Navigation', 'wp-rest'),
    ]);
}
add_action('after_setup_theme', 'wp_rest_register_menus');
```

### Block Registration Process in `block-registration.php`

Handles custom block registration, ensuring seamless integration.

```php
require __DIR__ . '/textbox/acf.php';
require __DIR__ . '/textbox/preview.php';

function wp_rest_register_acf_blocks() {
    register_block_type(__DIR__ . '/textbox', [
        'render_callback' => 'textbox_block_render_callback',
    ]);
}
add_action('init', 'wp_rest_register_acf_blocks');
```

### Advanced Custom Fields Setup in `acf.php`

Defines field groups programmatically for API visibility.
Dig into the [ACF Documentation](https://www.advancedcustomfields.com/resources/register-fields-via-php/), or just export your ACF Field Groups via it's GUI to PHP and have a look at the generated code.
Alternatively you can stick with the GUI

### Preview Functionality in `preview.php`

Offers a backend glimpse of custom blocks, aiding in layout decisions. Here's an example of a preview for a simple text box block:

![Block Preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9znuaauc2yika3u4keb.png)

### Custom API Endpoint Creation in `endpoint-registration.php`

Explored further in Chapter 3, this script introduces tailored REST API endpoints.

## Linking Astro to WordPress

This segment outlines the pivotal step of connecting Astro to WordPress, focusing on API interactions and data presentation.

### Secure API Authentication

Ensure WordPress credentials are securely stored for API communication.

```plaintext
WORDPRESS_URL=https://your-wordpress-url.com
WORDPRESS_USER=your-username
WORDPRESS_SECRET=your-password
```

### Axios Client Setup

Demonstrates configuring Axios for API requests, adaptable to alternative libraries.

```javascript
import axios from 'axios';

const config = {
  baseURL: import.meta.env.WORDPRESS_STAGING_URL + '/wp-json/wp/v2/',
  headers: {
    'Content-Type': 'application/json',
  },
  auth: {
    username: import.meta.env.WORDPRESS_USER,
    password: import.meta.env.WORDPRESS_SECRET,
  },
};

export const fetchApi = axios.create(config);

fetchApi.interceptors.request.use(
  (config) => config,
  (error) => Promise.reject(error)
);
```

Further exploration on fetching WordPress data within Astro will continue in Chapter 3.

Feel free to share questions or feedback in the comments section.