GT ACF Blocks AJAX and REST Endpoints

  • JNext lesson
  • KPrevious lesson
  • FSearch lessons
  • EscClear search

Overview

The plugin exposes a small HTTP surface: two REST API routes (star rating submissions and the email form webhook proxy) plus admin-only AJAX endpoints through admin-ajax.php for the URL Preview block. A legacy admin-ajax action for star ratings is kept for cached pages running older scripts.

Public, cache-exposed interactions (star ratings, email form webhooks) run over REST, where cache-safe tokens work better than nonces. Editor-only interactions (URL Preview) stay on admin-ajax. This lesson documents each endpoint, its auth requirements, and what calls it, which is everything you need to debug or extend the interactive blocks.

Star Rating Submission

Flow diagram of a star rating submission from a cached page to the acf-blocks/v1/ratings REST route, validated by a per-block HMAC token, deduplicated by a localStorage flag and a daily voter hash, and stored with atomic SQL updates

Route: POST /wp-json/acf-blocks/v1/ratings
Auth: Public (anonymous submissions allowed; validated by a per-block HMAC token)
File: blocks/star-rating-block/extra.php

Accepts a star rating submission from a visitor and updates the aggregate atomically in dedicated database tables. The old acf_star_rating_submit admin-ajax action still works as a backward-compatible fallback for pages cached with the previous script.

Request Parameters

  • postId – The post ID being rated (required, must be > 0).
  • blockId – The unique block instance ID (required).
  • rating – The rating value, between 1 and 5 (required).
  • token – A cache-safe HMAC token rendered with the block (required). Unlike a nonce, it never expires with the page cache.
  • initialCount / initialRating – Optional seed values configured on the block, folded into the returned aggregate.

Response

On success, returns:

  • average – The new average rating (float, rounded to 2 decimals).
  • averageFormatted – Localized average (e.g. “4.2”).
  • count – Total number of ratings.
  • countText – Localized count text (e.g. “42 ratings”).

Storage

Ratings live in two dedicated tables: {prefix}acf_block_rating_votes (one row per vote, keyed by a privacy-preserving daily voter hash) and {prefix}acf_block_rating_totals (atomic count/sum aggregates). Atomic SQL updates mean concurrent votes are never lost. Legacy aggregates stored in the old _acf_star_rating_{block_id} post meta are seeded into the totals table on first use.

The frontend JavaScript stores a “rated” flag in localStorage (keyed by post ID + block ID) to prevent duplicate submissions from the same browser. Server-side, the daily voter hash catches duplicates that localStorage misses.

URL Preview Fetch

Action: acf_url_preview_fetch
Auth: Admin only (requires edit_posts capability)
File: blocks/url-preview/extra.php

Fetches a URL and extracts Open Graph metadata (title, description, image) for populating the URL Preview block fields.

Request Parameters

  • nonce – WordPress nonce for acf_url_preview_fetch (required).
  • url – The URL to fetch metadata from (required).

Response

On success, returns:

  • title – Page title (from og:title, twitter:title, or <title> tag).
  • description – Page description (from og:description or meta description). Truncated to 300 characters.
  • image – Image URL (from og:image, twitter:image, or first suitable <img> on the page).

Caching

Results are cached in a WordPress transient for 1 week. The cache key is acf_url_preview_{md5(url)}.

Metadata Extraction Priority

For each field, the parser tries sources in order:

Title: og:title -> twitter:title -> <title> tag

Description: og:description -> meta description

Image: og:image -> twitter:image -> first large <img> in content (skips images with width < 600px, data URIs, and common icon/logo patterns)

URL Preview Image Import

Action: acf_url_preview_import_image
Auth: Admin only (requires upload_files capability)
File: blocks/url-preview/extra.php

Downloads an external image and imports it into the WordPress media library.

Request Parameters

  • nonce – WordPress nonce for acf_url_preview_import (required).
  • image_url – The external image URL to import (required).
  • post_id – The post ID to attach the image to (optional).

Response

On success, returns:

  • attachment_id – The WordPress attachment ID of the imported image.
  • url – The local URL of the imported image.
  • message – Success message.

Deduplication

Before downloading, the handler checks for existing attachments with a _acf_url_preview_source meta value matching the image URL. If found, the existing attachment ID is returned without re-downloading.

Security

The URL preview endpoints verify WordPress nonces and check user capabilities. The star rating REST route accepts submissions from anonymous users (required for visitor ratings) and validates a per-block HMAC token plus a daily voter hash instead of a nonce, which keeps it reliable behind full-page caching. The email form proxy (POST /wp-json/email-form-proxy/v1/submit, registered by the Email Form block) relays webhook submissions server-side to avoid CORS restrictions.

Quick answers to common questions:

Why admin-ajax instead of the REST API?

Each transport fits its job. Public star ratings use a REST route with a cache-safe token because nonces expire inside cached pages. The email form proxy is REST for the same reason. URL Preview stays on admin-ajax: it only ever runs for logged-in editors, where nonce-in, JSON-out simplicity wins.

Are the AJAX endpoints secure?

Each verifies either a nonce and capability (URL Preview) or an HMAC token plus voter hash (star ratings) before doing anything. The lesson lists the exact checks per endpoint so you can audit them against your own security requirements.