=== BlueBook Feed Sync ===
Contributors: rstake, sdaweb
Tags: social feed, page feed, social media, feed widget, social sync
Requires at least: 5.8
Tested up to: 7.1
Stable tag: 3.14.1
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Display a customizable social page feed on your WordPress site with multiple layouts, color schemes, header options, like box, lightbox, and more.

== Description ==

BlueBook Feed Sync is a professional WordPress plugin that displays your social page feed with multiple layouts, full customization, multi-feed management, and an interactive lightbox. Easy setup, fully customizable, and lightweight. Multiple layouts, interactive lightbox, video support, and multi-feed management.

= Multi-Feed Manager =

Create unlimited feeds, each with their own settings. Perfect for sites that need different feeds on different pages.

* Feed selector dropdown to switch between feeds
* Create, duplicate, rename, and delete feeds
* New feeds automatically inherit connection settings from the primary feed
* Per-feed shortcodes with unique ID
* Override any setting directly in the shortcode

= Layouts =

* **List** — Single-column vertical feed (max-width 960px)
* **Masonry** — Pinterest-style multi-column grid
* **Carousel** — Multi-card horizontal slider with snap-based swipe navigation, dot indicators, and arrow buttons
* **Boxed** — Clean CSS Grid layout with subtle borders

= Header Styles =

**Visual Header** with 4 layout presets: Classic, Compact, Banner, and Clean.

**Text Header** with Facebook icon and custom text.

Both header types support custom backgrounds (theme, solid color, gradient, transparent), page name override, show bio toggle, and bio/description override.

= Lightbox =

All posts open in a split-layout lightbox with full-size image or inline video, post text, author info, engagement stats, thumbnail strip for multi-photo galleries, arrow and swipe navigation, and keyboard support. Infinite scroll — when you reach the last loaded post, the next batch loads automatically so you can keep browsing without leaving the lightbox. Text-only posts display in a clean full-width layout instead of a split view.

= Video Support =

* **YouTube** — Auto-detected from shared links with privacy-enhanced embedding
* **Facebook Videos** — Thumbnail with play button, embedded via Facebook plugin

= Color System =

Three built-in schemes (Inherit, Light, Dark) plus a full custom palette with 9 individually configurable colors.

== Installation ==

1. Download `bluebook-feed-sync.zip`.
2. In WordPress admin, go to **Plugins > Add New > Upload Plugin**.
3. Upload the zip file and click **Install Now**.
4. Activate the plugin.
5. Go to **BlueBook Feed** in the admin menu to configure your connection.

== Frequently Asked Questions ==

= How do I get a Facebook Access Token? =

You need to create a Meta (Facebook) App at developers.facebook.com, then use the Graph API Explorer to generate a Page Access Token. See the full guide in the plugin's admin page or the included README.md.

= Can I display multiple feeds on the same site? =

Yes. Use the Multi-Feed Manager to create additional feeds, each with their own settings. Display them using the shortcode with an ID parameter, e.g. `[bbfsync_feed id="2"]`.

= Can I override settings in the shortcode? =

Yes. Any setting key can be used as a shortcode attribute, e.g. `[bbfsync_feed layout="carousel" posts_desktop="6" color_scheme="dark"]`.

= How does caching work? =

The plugin caches API responses to minimize Facebook API calls. You can clear the cache from the Connect tab in the plugin settings (under "Advanced"). The minimum cache duration is 15 minutes.

= Can I extend the plugin from my theme or another plugin? =

Yes. As of 3.10.0 the plugin exposes 9 documented WordPress filter and action hooks covering Graph API field selection, post data and HTML rendering, cache duration, and lifecycle events. Full documentation with copy-paste examples lives in `docs/hooks.md` inside the plugin folder. Examples include: filtering posts by date before caching, adding badges to posts containing specific hashtags, busting your page cache when the feed refreshes, and overriding the Graph API field set. All hooks are stable within the 3.x major version.

== Screenshots ==

1. Admin settings — Connect tab with credential masking and connection status banner
2. Admin settings — Layout tab with visual layout picker
3. Admin settings — Style tab with colour scheme and header options
4. Feed display — List layout with lightbox
5. Feed display — Carousel layout

== Third-Party Services ==

This plugin connects to external services to retrieve and display social media content. No data is sent without your explicit configuration.

= Facebook Graph API =

Used to fetch page posts, page info (name, bio, avatar, cover photo), and to verify your access token.

* Service: Meta Platforms, Inc.
* Website: [https://developers.facebook.com/](https://developers.facebook.com/)
* Terms of Service: [https://developers.facebook.com/terms/](https://developers.facebook.com/terms/)
* Privacy Policy: [https://www.facebook.com/privacy/policy/](https://www.facebook.com/privacy/policy/)

Data sent: your Facebook Page ID and Page Access Token. Requests are made server-side when the feed cache expires or when you click "Verify Connection" in the admin panel.

= Facebook CDN (Image Hosting) =

Profile pictures, cover photos, and post images are loaded directly from Facebook's image servers (scontent.xx.fbcdn.net) when a page containing the feed is rendered. This means Meta can see the visitor's IP address as soon as the page loads, before any interaction.

* Service: Meta Platforms, Inc.
* Privacy Policy: [https://www.facebook.com/privacy/policy/](https://www.facebook.com/privacy/policy/)

= Facebook Video Embed =

When a visitor clicks play on a Facebook video, the video is embedded via an iframe from Facebook's servers.

* Service: Meta Platforms, Inc.
* Embed URL: https://www.facebook.com/plugins/video.php
* Terms of Service: [https://developers.facebook.com/terms/](https://developers.facebook.com/terms/)
* Privacy Policy: [https://www.facebook.com/privacy/policy/](https://www.facebook.com/privacy/policy/)

= YouTube =

On any page that displays the feed, the plugin loads the YouTube iframe API so that any YouTube videos shared in your posts can play inline. When a post actually contains a YouTube video, its thumbnail image is fetched from YouTube's servers.

* Service: Google LLC
* Website: [https://www.youtube.com/](https://www.youtube.com/)
* Terms of Service: [https://www.youtube.com/t/terms](https://www.youtube.com/t/terms)
* Privacy Policy: [https://policies.google.com/privacy](https://policies.google.com/privacy)

The YouTube iframe API script (https://www.youtube.com/iframe_api) is loaded on pages that display the feed. Thumbnail images are fetched from https://img.youtube.com/. Video embeds use the privacy-enhanced domain https://www.youtube-nocookie.com/.

= Open Graph Image Recovery =

When a shared post has no image from the Graph API, the plugin makes a single server-side HTTP request to the post's permalink or link target URL to extract the Open Graph (og:image) meta tag. This request is made from your web server, not from the visitor's browser. The recovered image URL is cached for one hour.

* This may connect to any website linked in a shared post (e.g., facebook.com, youtube.com, or any external URL shared on the page)
* Data sent: a standard HTTP GET request with a User-Agent header
* No visitor data is transmitted — the request originates from the server only
* Privacy policies of the target websites apply to their handling of these requests


== Changelog ==

The most recent releases are listed here. The complete history is in changelog.txt in the plugin folder.

= 3.14.1 =
* Fix: A percent sign in the "time ago" text (Components → Post Labels, or the `time_ago_format` shortcode attribute) — for example "%s ago (100%)" — caused a fatal error on PHP 8 on every page showing a post less than a week old. Such texts are now simply shown as written; ordinary texts like "%s ago" give exactly the same result as before.
* Accessibility: With the default button style, the lightbox's Close, Previous and Next buttons were invisible and had no focus ring for keyboard users unless the mouse pointer happened to be over the lightbox. When the keyboard is used they are now shown, and the focused button gets a ring. Nothing changes for mouse and touch.
* Accessibility: After moving to another post inside the lightbox, closing it lost the keyboard focus instead of returning it to the post that was opened. Focus now goes back to that post.
* Accessibility: On WordPress versions older than 7.1, post cards could not be reached with the Tab key on the first page load (posts added by "Load More" could). WordPress 7.1 and newer were not affected.

= 3.14.0 =
* New: The Connect tab now shows the real connection status — when Facebook last answered successfully, or why it is failing (token rejected, missing permission, wrong Page ID, rate limit, network error) together with Facebook's own message. Before, it only said "credentials configured".
* New: When Facebook rejects the Page Access Token (expired or revoked), the site administrator gets one email explaining what to do, at most once per day per feed, and the plugin's other settings tabs show a notice. Developers can change or disable the recipient with the `bbfsync_token_alert_recipient` filter.
* Fix: If your server could not reach Facebook (timeout, DNS or network failure), every uncached page view repeated up to ten 15-second attempts before showing the saved posts. A network failure now stops after the first attempt, and the plugin waits a few minutes before calling Facebook again; visitors see the saved posts immediately in the meantime.
* Fix: A broken response from Facebook (an error page instead of data) was stored as an empty feed and written over the backup copy. It is now treated as a failure, and an empty answer never replaces a backup that contains posts.
* Fix: "Posts on mobile" had no effect — every device showed the larger of the desktop and mobile numbers. Phones (up to 768px wide) now show the mobile number; "Load More" reveals the rest. If your mobile number is lower than your desktop number, phones will show fewer posts after this update, as the setting always described.
* Fix: Switching off "Image & Video Viewer" did not stop posts from opening in the lightbox. With the viewer off, photos now link to the post on Facebook, text-only posts expand in place, and videos play inline (Facebook videos open on Facebook on touch devices).
* Fix: Clicking the 2nd, 3rd… photo of a multi-photo post always opened the lightbox on the first photo. It now opens on the photo you clicked.
* Fix: The carousel layout only worked with the default 3 / 2 / 1 columns; any other column setting made the slides drift out of step. Card width now follows the column settings.
* Fix: "Load More" on feed #2 and higher used feed #1's cache slot.
* Developer: new action `bbfsync_api_fetch_failed` and filter `bbfsync_failure_cooldown`; the `bbfsync_cache_duration` filter now also applies to the page-info request, as documented. See docs/hooks.md.

== Upgrade Notice ==

= 3.14.1 =
Fixes a fatal error caused by a percent sign in the "time ago" text, and three keyboard-accessibility problems in the lightbox and post cards. No visible changes for mouse and touch users.

= 3.14.0 =
Real connection status and an email alert when Facebook rejects your token. Fixes slow pages during Facebook outages, the "Posts on mobile" setting, the lightbox on/off switch, gallery photo clicks and carousel columns.
