WP Manifestindependent plugin directory
manifest / social / facebook-social-feed

Facebook Social Feed

Displays recent posts from a Facebook Page on your WordPress website via the Meta Graph API, using secure server-side requests and the [facebook_social_feed] shortcode.

by Paradorn · github.com/paradonk/facebook-social-feed · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/paradonk/facebook-social-feed/archive/refs/heads/main.zip

Readme

Facebook Social Feed

Displays recent posts from a single Facebook Page on your WordPress website, retrieved server-side through the Meta Graph API, via the [facebook_social_feed] shortcode. Built with a security-first design: the Page access token never leaves the server.

Contents

Features

  • Server-side Graph API integration (wp_safe_remote_get()); the browser never talks to Facebook directly.
  • Access token and App Secret are never exposed in HTML, JavaScript, REST responses, logs, or public error messages.
  • Credentials can be defined in wp-config.php (recommended) or entered in the admin settings page.
  • Normalizes Facebook's response into a stable internal post format, filtering out Facebook's auto-generated boilerplate titles (e.g. "Photos from X's post").
  • Caches the feed with the WordPress Transients API; falls back to the last successfully retrieved feed if Facebook is temporarily unavailable.
  • Responsive grid (1-4 columns) and list layouts, framework-free CSS, with CSS custom properties for easy restyling.
  • Admin "Test Connection", "Refresh Feed Now", and "Clear Cache" actions (AJAX, nonce + capability protected).
  • Automatic refresh via WP-Cron.
  • Sanitized, mapped error handling for expired tokens, missing permissions, rate limiting, and transport failures.
  • Hooks (filters/actions) for developers; no required JavaScript to display the feed.

Requirements

  • WordPress 6.4 or later
  • PHP 8.0 or later
  • A Facebook Page and a Page access token with pages_read_engagement (or equivalent) permission

Installation

  1. Copy the facebook-social-feed folder into wp-content/plugins/.
  2. Activate Facebook Social Feed from the Plugins screen.
  3. Go to Settings → Facebook Social Feed and configure your Page ID and access token (or define them in wp-config.php, see below).
  4. Add the [facebook_social_feed] shortcode to any post or page.

Facebook/Meta prerequisites

You need:

  1. A Facebook Page you administer.
  2. A Meta App (developers.facebook.com) associated with that Page.
  3. A Page access token with permission to read the Page's posts. Generate a long-lived Page access token via the Graph API Explorer or your app's token flow; this plugin does not perform any OAuth flow itself.
  4. The Page's numeric Page ID (found in the Page's "About" section or via the Graph API Explorer).

This plugin does not create, refresh, or extend tokens for you. When your token expires, generate a new one and update it in wp-config.php or the settings page.

Configuration through WordPress

On Settings → Facebook Social Feed:

  • Connection settings: Page ID, Page access token, Graph API version (e.g. v23.0).
  • Feed settings: default number of posts, cache duration, default layout/columns, and which fields to show.
  • Maintenance: Test Connection, Refresh Feed Now, Clear Cache, plus status information (current cache status, last refresh, last successful refresh, last sanitized API error) and a Debug mode toggle.

The access token field is a password input that is never pre-filled with the saved value. It shows only Token saved: Yes/No. Leaving it blank on save preserves the existing token; check Remove the stored access token to clear it.

Recommended wp-config.php configuration

For better security, define credentials as constants instead of storing them in the database:

define( 'FSF_FACEBOOK_PAGE_TOKEN', 'replace-with-page-token' );
define( 'FSF_FACEBOOK_PAGE_ID', 'replace-with-page-id' );

When these constants are defined, they always take precedence over the database settings, the corresponding settings-page fields become read-only status displays, and the token is never rendered back into any admin field.

Shortcode usage

[facebook_social_feed]
[facebook_social_feed limit="6" columns="3" layout="grid"]
[facebook_social_feed limit="5" layout="list" show_image="no"]

Attributes

Attribute Type Range / values Falls back to settings if invalid
limit integer 1-20 yes
columns integer 1-4 yes
layout string grid, list yes
show_message boolean-ish yes/no/true/false/1/0 yes
show_date boolean-ish yes/no/true/false/1/0 yes
show_image boolean-ish yes/no/true/false/1/0 yes
open_new_tab boolean-ish yes/no/true/false/1/0 yes
class CSS class list sanitized as CSS classes n/a (empty if invalid)

The shortcode is safe to use more than once on the same page: assets are only enqueued once regardless of how many instances are rendered.

Styling / CSS customization

The frontend stylesheet (public/css/social-feed.css) exposes CSS custom properties on .fsf-feed, so you can restyle the feed from your theme without editing plugin files:

Property Default Controls
--fsf-gap 1.25rem Space between cards
--fsf-border-color #e2e2e2 Card and placeholder borders
--fsf-border-radius 8px Card corner radius
--fsf-background #ffffff Card background
--fsf-text-color #1d1d1d Primary text color
--fsf-muted-color #6b6b6b Date and status-message color
--fsf-link-color #1877f2 "View post on Facebook" link color
--fsf-columns 3 Grid column count (set via shortcode/settings, not usually overridden directly)
--fsf-card-height 440px Total height of each grid card
--fsf-card-media-height 260px Height of the image/video thumbnail area in grid cards
--fsf-card-message-lines 3 Number of message lines shown before truncating with an ellipsis (grid cards)

Grid cards are a fixed, uniform height with the title clamped to 2 lines and the message/description clamped to --fsf-card-message-lines; overflowing text is clipped rather than growing the card. List layout is left flexible (image beside text, height follows content) since forcing uniform height there tends to crop images awkwardly.

Example override, e.g. in your theme's Additional CSS:

.fsf-feed--grid {
    --fsf-card-height: 500px;
    --fsf-card-media-height: 300px;
    --fsf-card-message-lines: 4;
}

Caching behavior

  1. If a fresh, unexpired cache exists (WordPress Transients API), it is returned immediately -- no Graph API request is made.
  2. If the cache has expired, the plugin requests fresh data (guarded by a 60-second refresh lock so concurrent visitors/cron do not trigger duplicate requests).
  3. On success, the fresh data is cached for the configured duration and also stored as the "last successful feed".
  4. On failure, the last successful feed is served instead (with the error recorded, sanitized, for administrators only). If no previous feed exists yet, a generic "temporarily unavailable" message is shown.

Cache duration options: 15 minutes, 30 minutes, 60 minutes (default), 2 hours, 4 hours, 12 hours, 24 hours.

WP-Cron behavior

A single WP-Cron event (fsf_refresh_facebook_feed) is scheduled hourly on activation and unscheduled on deactivation. Because the cache duration is configurable up to 24 hours while the cron event itself runs hourly, the cron handler only contacts the Graph API when the live cache has actually expired -- otherwise it is a no-op. This avoids the complexity of per-duration custom cron recurrences while still respecting the configured cache duration.

Error handling

Facebook/Graph API errors are mapped to internal WP_Error codes (fsf_missing_page_id, fsf_missing_token, fsf_invalid_token, fsf_missing_permission, fsf_page_not_found, fsf_rate_limited, fsf_http_error, fsf_transport_error, fsf_invalid_json, fsf_empty_response, fsf_api_error) with human-readable, sanitized messages. Public visitors never see raw API responses or technical details -- only "No Facebook posts are available at this time." or "Facebook updates are temporarily unavailable." (and only when no cached feed exists at all). Administrators can see the sanitized error message plus the Meta error code/subcode on the settings page.

Token security

  • The access token is never printed into frontend HTML, JavaScript, REST responses, or public error output.
  • The token field on the settings page is never pre-filled with the real value.
  • Logging (only active when Debug mode is enabled) redacts tokens, App Secrets, and access_token=.../Bearer ... patterns from any logged string.
  • The Graph API host is hard-coded to graph.facebook.com; only the API version is configurable, never an arbitrary hostname.
  • The token is excluded from the plugin's own diagnostic display and from log output.

Troubleshooting

Symptom Likely cause
"The Facebook access token is invalid or expired." The token expired or was revoked; generate a new Page access token.
"The application does not have permission to read this Facebook Page." The token/app lacks the required Page permission.
"The configured Facebook Page could not be found or is not accessible with this token." Wrong Page ID, or the token does not belong to that Page.
"The Facebook API rate limit has been reached." Too many requests in a short window; the plugin will retry on the next cache expiry.
Feed shows old content Expected -- the cache is still fresh, or a previous request failed and the last-known-good feed is being shown. Use "Refresh Feed Now" to force an update.

Enable Debug mode on the settings page to log sanitized, high-level events (refresh started/completed, post count, HTTP status, sanitized Graph error code) to the PHP/WordPress error log.

Development notes

  • Namespace: Paradorn\FacebookSocialFeed. Classes are autoloaded from includes/class-{kebab-case-name}.php.
  • No Composer dependency, no jQuery, no frontend CSS framework.
  • tests/fixtures/ contains sanitized Graph API JSON fixtures for manual/local development without live credentials; see tests/README.md for the full manual test plan.
  • This plugin was developed and reviewed without a local PHP CLI available for php -l; run a syntax/lint pass (php -l, PHPCS with the WordPress ruleset) in your own environment before deploying to production, and complete a live Graph API test as described in tests/README.md.

Hooks for developers

Filters:

Hook Purpose
fsf_api_fields Change the Graph API fields parameter.
fsf_api_post_limit Adjust the number of posts requested from the API (still capped at 25).
fsf_normalized_post Modify a single normalized post array.
fsf_normalized_posts Modify the full normalized posts array.
fsf_cache_duration Override the effective cache duration (seconds).
fsf_shortcode_attributes Modify the default shortcode attributes (from settings) before validation.
fsf_feed_template / fsf_feed_item_template Override the template file path for the feed wrapper / a single item.
fsf_formatted_message Modify the formatted (already-escaped) post message HTML.
fsf_formatted_date Modify the formatted post date string.

Actions:

Hook Fires
fsf_before_feed_refresh Before a Graph API refresh attempt starts.
fsf_after_feed_refresh After a successful refresh, with the normalized posts.
fsf_feed_refresh_failed After a failed refresh, with the WP_Error.
fsf_before_feed_render Before the shortcode output is built.
fsf_after_feed_render After the shortcode output is built.

The access token is never passed to any filter or action.

Release procedure

  1. Update CHANGELOG.md and the Stable tag / version headers in facebook-social-feed.php and readme.txt.
  2. Run php -l across all PHP files and, if available, PHPCS with the WordPress Coding Standards ruleset.
  3. Work through tests/README.md manually, including at least one live Graph API test against a real Page/token.
  4. Zip the plugin directory (excluding tests/ and VCS metadata, if desired) and tag the release.

License

GPLv2 or later. See LICENSE.

Read the full README on GitHub →