=== Keryx Signage ===
Contributors: dfloresvel
Donate link: https://ko-fi.com/dfloresv
Tags: digital-signage, signage, kiosk, display, slideshow
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.13.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Turn any WordPress post into a digital signage screen with one click — a public, no-login player URL for your TVs and displays.

== Description ==

Keryx Signage turns your WordPress site into a digital signage system — no per-screen fee, no third-party cloud dashboard, no login required on the screen itself. Enable "Show on screens" on any post, pick (or quick-create) a Display, and publish: the plugin generates a slide, keeps it in sync with the post automatically, and gives you a public player URL ready to open on any TV, kiosk, or Raspberry Pi browser.

**Publish to Signage**

Add a post, open the "Signage" panel in the editor sidebar, choose a template and a target Display, and publish. The slide is created and kept in sync automatically: editing the post updates the slide, unpublishing or trashing it removes the slide from rotation without deleting any data, and republishing brings it right back.

**7 slide templates**

Image + text, image only, text only, large title, featured quote, full image with a bottom bar, and a 50/50 split layout — each with a live CSS preview right in the editor panel.

**Background video**

Play a self-hosted MP4/WebM file (picked straight from your Media Library, no third-party player or branding), or a YouTube or Vimeo URL, as a slide's fit-to-screen background. See "External services" below for what loading a YouTube/Vimeo URL means for your visitors.

**Clock overlay**

An optional digital or analog clock, in any corner, 12- or 24-hour format — configured once per Display.

**Text color customization**

Pick a background and text color for every solid text area across all templates, from a single pair of settings per Display, with sensible defaults so it looks good without touching anything.

**Fit-to-screen player**

The public player is a bare fullscreen page — no theme header, footer, or widgets — built to fill commercial displays edge-to-edge without zoom or letterboxing, with a smooth crossfade between slides and a soft, in-place refresh (no page reload, no flicker) whenever content changes.

**"What plays on this screen"**

The Display editor shows every slide currently linked to that screen, in playback order, with its source post, template, background type, duration, and live/draft status — so you always know what's actually showing.

= Requirements =

* WordPress 6.4+
* PHP 7.4+

== Installation ==

1. Upload the plugin to the `/wp-content/plugins/` directory, or install it through the Plugins screen in WordPress.
2. Activate the plugin through the "Plugins" screen.
3. Go to **Signage → Add New Display** and create a Display (give it a name; a public player URL is generated automatically).
4. Edit any post, open the **Signage** panel in the sidebar, check "Show on screens", pick your Display, and publish.
5. Open the Display's public URL (shown in the Signage panel and in **Signage → Displays**) on the screen or kiosk browser you want to use.

== External services ==

This plugin connects to Freemius, a third-party service, to manage optional Pro license activation, software updates for the Pro add-on, and checkout. This connection is only used if you choose to opt in; the free plugin is fully functional without it.

Data sent to Freemius may include: your site URL, WordPress version, PHP version, active theme and plugins, and the email address you provide during opt-in or purchase. This data is sent when you opt in, activate or deactivate a license, or check for Pro updates. No data is sent if you skip the opt-in.

Freemius is operated by Freemius, Inc.
- Terms of Service: https://freemius.com/terms/
- Privacy Policy: https://freemius.com/privacy/

Keryx Signage does not contact YouTube or Vimeo on its own. It only loads their embed if YOU set a YouTube or Vimeo URL as a slide's background video (in the "Signage" panel on a post). Self-hosted MP4/WebM video, images, and text-only slides never contact any third-party service. When you do set a YouTube or Vimeo URL:

* **YouTube**: the public player page loads YouTube's IFrame Player API (`https://www.youtube.com/iframe_api`) and embeds the video via `https://www.youtube.com/embed/…`. This happens every time that slide is shown on a screen. YouTube (Google) may set cookies and receive the viewer's IP address and browser information, per its own policies: [Google Privacy Policy](https://policies.google.com/privacy), [YouTube Terms of Service](https://www.youtube.com/t/terms).
* **Vimeo**: the public player page embeds the video via an iframe pointing at `https://player.vimeo.com/video/…`. This happens every time that slide is shown on a screen. Vimeo may set cookies and receive the viewer's IP address and browser information, per its own policies: [Vimeo Privacy Policy](https://vimeo.com/privacy), [Vimeo Terms of Service](https://vimeo.com/terms).

No data about your WordPress site, its users, or its content is sent to YouTube or Vimeo beyond what loading their embed necessarily requires (the video ID and the viewer's own request). No API keys or account credentials are used or required for either.

The "Web page (URL)" slide type shows a web address YOU enter as a slide, loaded full-screen in a sandboxed iframe on the public player. This only happens for a slide you explicitly set up this way, pointing at a URL you choose. When such a slide is shown:

* The screen's own browser loads the exact URL you configured, directly, every time that slide is displayed. That site's server receives the viewer's IP address and request like any normal page visit, and the page may set its own cookies or load its own third-party resources — all outside this plugin's control. Nothing about your WordPress site, its users, or its content is sent beyond the URL itself and the viewer's own request.
* Your WordPress server makes one HEAD request to that URL when you save the slide or press "Check this URL" in the editor, purely to detect whether the site permits being embedded (via its X-Frame-Options / Content-Security-Policy headers). Only the response headers are read — the page body is never fetched or stored — and the result is cached. No server-side request to the URL is made while the player is running.

No API key or account credentials are used or required.

== Frequently Asked Questions ==

= Does this plugin connect to any external service? =

Not on its own. Every connection is optional, under your control, and described in "External services" above:

* **Freemius** — only if you opt in when prompted after activation. The opt-in is skippable, and the free plugin works completely without it.
* **YouTube / Vimeo** — only if you set a YouTube or Vimeo URL as a slide's background video, and only for that slide.
* **A "Web page (URL)" slide** — only if you create one: the screen's browser then loads the exact page you entered, and your server makes one HEAD request to it when you save or check the URL in the editor.

= Do I need an account or subscription? =

No. Keryx Signage runs entirely on your own WordPress site: no per-screen fee, and no required third-party cloud service. (There is an optional Freemius opt-in tied to the separate paid add-on; it can be skipped — see "External services".)

= Does the screen need to be logged in to WordPress? =

No. The public player URL (`/signage/your-display/`) works in any browser with no WordPress session or credentials.

= What happens if I unpublish or trash the source post? =

Its slide is automatically removed from rotation. No data is deleted — republishing the post brings the slide straight back.

= Can one post go to multiple screens? =

Yes. Check as many Displays as you like in the "Signage" panel, or create a Group of Displays under Signage → Groups and check that instead — the post reaches every Display in the group. Adding or removing a Display from a Group later automatically updates every post already assigned to it, with no need to re-save those posts.

= How often does a screen refresh its content? =

The player polls for updates roughly every 45 seconds.

== Screenshots ==

1. The "Signage" panel in the post editor — template picker, duration, and background video options.
2. The public, fullscreen player, showing a Split 50/50 slide.
3. "What plays on this screen" — every slide on a Display, in playback order, with its live/draft status.
4. The Display's "Screen Settings" — resolution preset, clock overlay, and text-zone color pickers.

== Changelog ==

= 0.13.0 =
* "Web page (URL)" slides are now unlimited in the free plugin: the 0.11.0 site-wide 1-slide cap is removed. Every published "Web page (URL)" slide shows on its assigned screen(s), same as every other slide type — no license check anywhere in that path. Keryx Signage Pro's URL-embed differentiation is now solely its pre-built weather, world-clock, and headline (RSS) widget library, which doesn't depend on a page being embeddable — code that lives entirely in the Pro add-on, not a locked-down piece of the free plugin.
* Removed the "the free plugin shows one web page slide..." notice and its "Upgrade to Pro" link from the Signage panel, and the matching AJAX/REST logic — none of it applies anymore.

= 0.12.0 =
* Renamed from Simple Signage Studio to Keryx Signage — new slug (`keryx-signage`), new text domain, new internal prefix throughout. A clean rename with no upgrade path: no users or data to migrate. If you had the old plugin installed, remove it and install this one fresh.
* "What plays on this screen": removed the disabled drag-to-reorder handle, on/off checkbox, and Schedule column that previously rendered in the free plugin — those were Pro-only controls shown non-interactive, which does not meet WordPress.org's guidelines on locked/inactive functionality. Replaced with a single plain-text note naming the Pro-only features, with a link to Keryx Signage Pro when relevant. No change for licensed Pro users, whose interactive reorder/toggle/scheduling still appears in the same place.
* Moved "Tested up to" out of the plugin's main PHP file — it now lives only in readme.txt, matching WordPress.org convention.
* Added an inline comment on the public REST endpoint's `permission_callback` clarifying that it is intentionally open (the signage player runs with no WordPress session), per WordPress.org's REST API guidance.

= 0.11.0 =
* New "Web page (URL)" slide type: show any http(s) web address full-screen on a screen, in a sandboxed iframe — a live dashboard, a status page, a shared calendar. Enter the URL in the "Signage" panel; a "Check this URL" button warns up front if the site refuses to be embedded (X-Frame-Options / CSP). If a page is slow or blocked, the screen shows a brief message and rotation carries on — it never sits blank.
* At the time, the free plugin rendered one such slide across the whole site. **Superseded in 0.13.0 — see above: this cap is removed, "Web page (URL)" slides are unlimited in the free plugin.** A Keryx Signage Pro license (a separate add-on) adds pre-built weather, world-clock and headline (RSS) widgets that don't depend on a page being embeddable.
* See "External services" for exactly what loading a third-party URL on a screen involves — no API key or account is used.

= 0.10.0 =
* "Portrait-safe" fix for the public player: no template broke in a vertical/9:16 viewport before, but the Split 50/50 template rendered as two cramped side-by-side strips instead of stacking, and long text could crowd more than intended on a much taller screen. A portrait-only adjustment (keyed off the actual viewport shape, not the Display's Resolution preset) now stacks Split 50/50's image/text zones and trims text sizing on the templates that shared that risk. Landscape/16:9 rendering, fit-to-screen, and every other template are unaffected. Not a portrait redesign — the templates still look and behave exactly as before in landscape.

= 0.9.0 =
* Added the hooks the Pro add-on's dayparting feature connects through (a "Schedule" column on "What plays on this screen", plus filters for whether a slide is currently in its scheduled window) — no behavior change for the free plugin on its own: every slide still always shows, exactly as before.

= 0.8.0 =
* Added the hooks the Pro add-on's instant push feature connects through (a handful of `do_action()` calls and one filter on the player's config) — a content or Screen Settings change can now reach a licensed, connected screen in seconds instead of waiting for the next ~45s poll. Polling itself is unchanged and still runs on every screen, licensed or not — it's the permanent fallback, never removed.
* No behavior change for the free plugin on its own: every new hook has a default that reproduces exactly what happened before this version.

= 0.7.0 =
* Drag-to-reorder and the per-slide on/off switch on "What plays on this screen" are now real, working features — available with a valid Keryx Signage Pro license (a separate add-on). Without Pro, they render exactly as before: visible for reference, not interactive.
* Added the licensing infrastructure (Freemius) the Pro add-on connects through. Nothing here changes what the free plugin does on its own — it keeps working fully standalone, with no account or add-on required.

= 0.6.0 =
* Added multi-display support: a post can now be assigned to several Displays at once from the "Signage" panel, instead of just one.
* Added Groups (Signage → Groups): a named, saved set of Displays. Assign a post to a Group instead of individual Displays, and every current (and future) member of that Group receives it — adding or removing a Display from a Group automatically updates every post already assigned to it, no re-saving needed.
* Added an "Add to group" bulk action to the Displays list, to add several screens to a Group at once.
* Existing single-Display assignments are migrated automatically and keep working exactly as before.

= 0.5.1 =
* Fixed a bug where changing a Display's clock or text color settings only reached an already-open screen after a full page reload — on some smart TV browsers, that reload may never happen on its own. Screen Settings changes now reach an open screen within one polling cycle (about 45 seconds), applied instantly and silently, without a slide crossfade or the "updating" badge.

= 0.5.0 =
* Added a text area background color and text color to each Display's Screen Settings, applied consistently across every solid text zone (Text only, Featured quote, Large title, Split 50/50's text side, and the caption bar of Full image + bottom bar). Text over an image or video background is unaffected and keeps its existing readability gradient.

= 0.4.0 =
* Added a "What plays on this screen" panel to the Display edit screen: every slide linked to that screen, in playback order, with its source post, template, background type, duration, and Published/Draft status — plus a "View screen" shortcut to the public URL. Drag-to-reorder and per-slide on/off are shown as disabled Pro-feature placeholders; this version is read-only.

= 0.3.0 =
* Added a self-hosted MP4/WebM background video option, selected from the Media Library, using a native HTML5 `<video>` element (no iframe). It takes priority over a YouTube/Vimeo URL when both are set; full priority order: uploaded video → YouTube/Vimeo URL → featured image → text-only fallback.
* Fixed a bug where a post's paragraph breaks were lost on the player, flattening multi-paragraph text into one run-on block. Paragraphs and line breaks are now preserved.
* Added a discreet fullscreen toggle button to the player, for TVs/browsers where fullscreen isn't automatic. It only appears briefly on mouse/touch/key activity and never overlaps the clock or the "updating" badge.

= 0.2.1 =
* Fixed a Split 50/50 layout bug where a background video could overflow into the text column instead of staying in its own half.
* YouTube background videos now use the YouTube IFrame Player API instead of a plain embed, so captions can be reliably turned off (`unloadModule`) even on videos where the uploader forced them on, and playback autoplay is verified as actually starting rather than assumed.

= 0.2.0 =
* Added a clock overlay (digital or analog, configurable position and time format) per Display.
* Added 4 more slide templates (large title, featured quote, full image with a bottom bar, split 50/50), each with a CSS preview in the editor panel.
* Added an optional YouTube/Vimeo background video per post, with a fit-to-screen crossfade-safe player and an optional sound toggle (muted by default).
* The player now does a soft, in-place refresh when polling detects a change to the slide on screen, instead of only picking it up on the next natural rotation.

= 0.1.0 =
* Initial release: Publish-to-Signage editor panel, per-slide duration, and a fullscreen fit-to-screen public player.

== Upgrade Notice ==

= 0.11.0 =
New "Web page (URL)" slide type — show a live web page full-screen on a screen.

= 0.2.0 =
Clock overlay, more slide templates, and optional background video.

= 0.1.0 =
Initial release.
