222 lines
9.9 KiB
Text
222 lines
9.9 KiB
Text
=== OpenGraph (by ROBOTSTXT) ===
|
|
Contributors: javiercasares, robotstxt
|
|
Tags: opengraph, open graph, twitter card, social media, seo
|
|
Requires at least: 6.8
|
|
Tested up to: 7.0
|
|
Stable tag: 1.1.0
|
|
Requires PHP: 8.2
|
|
Version: 1.1.0
|
|
License: GPL-3.0-or-later
|
|
License URI: https://www.gnu.org/licenses/gpl-3.0.txt
|
|
|
|
Intelligent Open Graph meta tags with automatic image fallback from AVIF/WebP to JPEG/PNG for social media crawlers.
|
|
|
|
== Description ==
|
|
|
|
Social media crawlers — Facebook, Twitter/X, LinkedIn, WhatsApp — do not support modern image formats such as AVIF and WebP. When a post's featured image uses one of these formats, the platform shows a broken or missing image preview.
|
|
|
|
**OpenGraph (by ROBOTSTXT)** outputs a complete set of Open Graph and Twitter Card meta tags and solves the format incompatibility automatically. It detects whether each post's featured image is in a supported format and, when needed, resolves and caches a compatible JPEG or PNG alternative.
|
|
|
|
**How it works:**
|
|
|
|
1. A visitor (or social media crawler) requests a page.
|
|
2. The plugin checks whether the post's featured image is in AVIF, WebP, or another unsupported format.
|
|
3. If so, it locates a JPEG or PNG version of the same image using HTTP HEAD requests.
|
|
4. The result is cached in postmeta so subsequent requests are instant.
|
|
5. The resolved image is injected into `og:image` (and related) meta tags.
|
|
|
|
**Key features:**
|
|
|
|
* Full Open Graph meta tag output: `og:title`, `og:type`, `og:url`, `og:description`, `og:site_name`, `og:locale`, `og:image`, `og:image:width`, `og:image:height`, `og:image:type`, `og:image:alt`
|
|
* Article-specific tags: `article:published_time`, `article:modified_time`, `article:section`, `article:tag`
|
|
* Twitter Card tags: `twitter:card`, `twitter:site`, `twitter:image`
|
|
* Automatic format detection — AVIF, WebP, GIF, BMP, SVG, TIFF
|
|
* HTTP HEAD-based image verification (no file downloads)
|
|
* Per-post custom OG title and description override (post editor meta box)
|
|
* Global fallback image URL and homepage-specific image URL
|
|
* Cached results in postmeta for performance, with automatic invalidation on featured image change
|
|
* Negative caching for failed resolutions (1-hour transient)
|
|
* Integration with Yoast SEO and RankMath (no duplicate tags)
|
|
* Taxonomy archive image support via developer filter
|
|
* Admin panel with Settings, Tools, and Diagnostics tabs
|
|
* WP-CLI commands for batch operations
|
|
* REST API endpoints for programmatic access
|
|
* Multisite compatible (per-site configuration)
|
|
* Full internationalization support (es_ES and ca included)
|
|
|
|
== Using the plugin ==
|
|
|
|
= WP-CLI =
|
|
|
|
List available commands:
|
|
|
|
`wp og-fallback --help`
|
|
|
|
Resolve the fallback image for a single post:
|
|
|
|
`wp og-fallback resolve 123`
|
|
|
|
Re-resolve all posts (clears cache first):
|
|
|
|
`wp og-fallback resolve --all`
|
|
|
|
Dry-run re-resolution without saving:
|
|
|
|
`wp og-fallback resolve --all --dry-run`
|
|
|
|
Re-resolve all posts of a specific type:
|
|
|
|
`wp og-fallback resolve --all --post-type=page`
|
|
|
|
Clear cache for a single post:
|
|
|
|
`wp og-fallback clear-cache 123`
|
|
|
|
Clear all cached fallback URLs:
|
|
|
|
`wp og-fallback clear-cache --all`
|
|
|
|
= REST API =
|
|
|
|
The plugin exposes two REST API endpoints under the `robotstxt-og/v1` namespace. Both require the `edit_others_posts` capability (editor and above).
|
|
|
|
**Force re-resolve a post's fallback image:**
|
|
|
|
`POST /wp-json/robotstxt-og/v1/resolve/{post_id}`
|
|
|
|
Returns: `{ post_id, resolved_url, cached, success }`
|
|
|
|
**Get current cached status for a post:**
|
|
|
|
`GET /wp-json/robotstxt-og/v1/status/{post_id}`
|
|
|
|
Returns: `{ post_id, cached_url, original_url, has_cache }`
|
|
|
|
== Extra Configurations ==
|
|
|
|
Developer filters available in `functions.php` or a custom plugin:
|
|
|
|
**Disable external image resolution:**
|
|
|
|
`add_filter( 'robotstxt_og_external_image_enabled', '__return_false' );`
|
|
|
|
**Adjust HEAD request timeout (seconds, default: 5):**
|
|
|
|
`add_filter( 'robotstxt_og_external_image_timeout', fn() => 10 );`
|
|
|
|
**Provide an OG image for taxonomy archives:**
|
|
|
|
`add_filter( 'robotstxt_og_taxonomy_image', fn( $url, $term_id ) => wp_get_attachment_url( get_term_meta( $term_id, 'my_image_id', true ) ), 10, 2 );`
|
|
|
|
**Enable debug logging to debug.log:**
|
|
|
|
`add_filter( 'robotstxt_og_enable_logging', '__return_true' );`
|
|
|
|
== Installation ==
|
|
|
|
= Automatic download =
|
|
|
|
Visit the plugin section in your WordPress dashboard, search for **OpenGraph by ROBOTSTXT**, then download and install the plugin.
|
|
|
|
= Manual download =
|
|
|
|
Extract the contents of the ZIP and upload the folder to the `/wp-content/plugins/robotstxt-og/` directory. Once uploaded, it will appear in your plugin list and can be activated normally.
|
|
|
|
= After activation =
|
|
|
|
1. Go to **Settings > OpenGraph**.
|
|
2. Optionally set a **Global Fallback Image** (paste a direct JPEG or PNG URL) to use when no compatible alternative is found.
|
|
3. Optionally set a **Homepage Image** for the site front page.
|
|
4. Configure your **Twitter/X site handle** (e.g. `@example`) if you want `twitter:site` output.
|
|
5. Use the **Tools** tab to re-resolve all existing posts in one click.
|
|
6. Use the **Diagnostics** tab to view cached entries and test individual URLs.
|
|
|
|
== Frequently Asked Questions ==
|
|
|
|
= Does this plugin duplicate og:image tags from Yoast SEO or RankMath? =
|
|
|
|
No. When Yoast SEO or RankMath is active, the plugin hooks into their existing filter (`wpseo_opengraph_image` or `rank_math/opengraph/facebook/og_image`) instead of injecting tags directly. The result is a single `og:image` tag, with the resolved fallback applied only when needed.
|
|
|
|
= Will it work if my images are stored on an external CDN? =
|
|
|
|
Yes. The plugin sends HTTP HEAD requests to verify alternative URLs, so it works with any URL-accessible image regardless of where it is hosted. You can disable external image resolution entirely with the `robotstxt_og_external_image_enabled` filter if needed.
|
|
|
|
= Why aren't AVIF/WebP images supported directly? =
|
|
|
|
AVIF and WebP are not supported by the Open Graph specification as implemented by major social media crawlers (Facebook, LinkedIn, WhatsApp, etc.). These platforms render a broken image or no image at all when an unsupported format is provided. This plugin works around that limitation by serving a JPEG/PNG fallback.
|
|
|
|
= What happens if no JPEG/PNG alternative is found? =
|
|
|
|
The plugin falls back to the **Global Fallback Image** configured in Settings > OpenGraph. If no fallback image is set, no `og:image` tag is injected for that post, leaving any existing tag from your SEO plugin in place.
|
|
|
|
= Is the cache refreshed automatically? =
|
|
|
|
Yes. When you change or remove a post's featured image, the cached fallback URL is cleared automatically. The new image will be resolved on the next page view, or can be forced immediately via WP-CLI (`wp og-fallback resolve <id>`) or the REST API.
|
|
|
|
= Does it work on WordPress Multisite? =
|
|
|
|
Yes. Each site in the network has its own independent configuration. There is no network-wide settings panel.
|
|
|
|
= Can I use this with classic themes and block themes? =
|
|
|
|
Yes. The plugin hooks into `wp_head` for direct tag injection and filters Yoast/RankMath when those plugins are active. It is compatible with both classic and block-based themes.
|
|
|
|
== Compatibility ==
|
|
|
|
* WordPress: 6.8 - 7.0
|
|
* PHP: 8.2 - 8.5
|
|
* WP-CLI: 2.x
|
|
* MariaDB: 10.6+
|
|
|
|
**Compatible SEO plugins:**
|
|
|
|
* Yoast SEO (integration via `wpseo_opengraph_image` filter)
|
|
* RankMath (integration via `rank_math/opengraph/facebook/og_image` filter)
|
|
|
|
== Changelog ==
|
|
|
|
= 1.1.0 =
|
|
|
|
_Release date: 2026-03-28_
|
|
|
|
* Fixed: Fatal `TypeError` in `handle_thumbnail_change()` when `deleted_post_meta` passes an array of meta IDs as the first argument.
|
|
* Security: Added SSRF protection — outbound HEAD requests now block private and reserved IP ranges.
|
|
* Security: Replaced deprecated `FILTER_SANITIZE_SPECIAL_CHARS` with `FILTER_SANITIZE_FULL_SPECIAL_CHARS`.
|
|
* Added: GDPR Privacy API — custom OG title and description are included in WordPress personal data export and erase.
|
|
* Changed: Settings page and REST API now require `edit_others_posts`, allowing editors to manage OG settings.
|
|
* Changed: Minimum supported WordPress version raised to 6.8.
|
|
* Changed: Added `Network: true` header confirming Multisite compatibility.
|
|
* Added: PHPUnit test suite (Brain\Monkey) covering SSRF protection, format detection, and cache clearing.
|
|
|
|
= 1.0.0 =
|
|
|
|
_Release date: 2026-02-18_
|
|
|
|
* Initial stable release.
|
|
* Full Open Graph meta tag output: `og:title`, `og:type`, `og:url`, `og:description`, `og:site_name`, `og:locale`, `og:image`, `og:image:width`, `og:image:height`, `og:image:type`, `og:image:alt`.
|
|
* Article-specific tags for singular posts: `article:published_time`, `article:modified_time`, `article:section`, `article:tag`.
|
|
* Twitter Card tags: `twitter:card`, `twitter:site`, `twitter:image`.
|
|
* Automatic format detection (AVIF, WebP, GIF, BMP, SVG, TIFF) with HTTP HEAD-based JPEG/PNG fallback resolution.
|
|
* Postmeta caching with automatic invalidation on featured image change.
|
|
* Per-post OG title and description overrides via post editor meta box.
|
|
* Global fallback image URL and homepage-specific image URL settings.
|
|
* Yoast SEO and RankMath integration (no duplicate tags).
|
|
* Admin settings page with Settings, Tools, and Diagnostics tabs.
|
|
* WP-CLI commands: `resolve` and `clear-cache`.
|
|
* REST API endpoints: `POST /resolve/{id}` and `GET /status/{id}`.
|
|
* Negative caching via transients (1-hour TTL) for failed URL checks.
|
|
* Multisite compatible.
|
|
|
|
= Previous versions =
|
|
|
|
This is the first release. For the full changelog, visit the [changelog.txt](https://git.robotstxt.es/ROBOTSTXT/robotstxt-og/raw/branch/main/changelog.txt) file.
|
|
|
|
== Compliance ==
|
|
|
|
This plugin adheres to the following security measures and review protocols for each version:
|
|
|
|
* [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/)
|
|
* [WordPress Plugin Security](https://developer.wordpress.org/plugins/wordpress-org/plugin-security/)
|
|
* [WordPress APIs Security](https://developer.wordpress.org/apis/security/)
|
|
* [WordPress Coding Standards](https://github.com/WordPress/WordPress-Coding-Standards)
|
|
* [Plugin Check (PCP)](https://wordpress.org/plugins/plugin-check/)
|