=== Related Posts by Zyonix Digital ===
Contributors: archatok
Tags: related posts, related content, similar posts, post recommendations, content discovery
Requires at least: 5.0
Tested up to: 7.1
Stable tag: 1.0.6
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Show related posts after your content. Supports grid/list layouts, excerpt, date, read time, Load More, shortcode and widget.

== Description ==

**Related Posts by Zyonix Digital** automatically shows related posts to your readers at the end of any post or page — helping you reduce bounce rates and keep visitors engaged longer.

= Key Features =

* **Category & Tag Matching** — Related posts share a category **or** a tag with the current post.
* **Optional Author Matching** — When enabled, results must also be by the same author.
* **Custom Taxonomy Matching** — Optionally match on public custom taxonomies attached to your query post types.
* **Show On / Query From** — Choose which post types automatically display the section, and which types can appear as related results. Shortcode and widget still work on other public types.
* **Grid & List Layouts** — Choose the layout that fits your theme.
* **Order By** — Latest, Most Commented, Random, or Relevance.
* **Deterministic Random** — Random order uses a signed seed so Load More continues the same shuffled pool without repeats.
* **Relevance Ranking** — Scores candidates by shared categories, tags, enabled custom taxonomies, overlap, and post type.
* **AJAX Load More** — Load additional related posts without a page reload. Already-shown IDs are excluded on the server.
* **ID Caching** — Related IDs are stored in transients (not HTML). Public/published checks still run when posts are rendered.
* **Post Meta** — Optionally show publish date and estimated reading time.
* **Excerpt Support** — Show a short excerpt beneath each related post title.
* **Shortcode** — Use `[zyonrp_related_posts]` anywhere in your content or widgets.
* **Widget Support** — Drop the widget into any sidebar or footer area.
* **Thumbnail Size** — Choose from Thumbnail, Medium, Medium Large, or Large.
* **Open in New Tab** — Optionally open all related post links in a new tab.
* **Auto-Append Toggle** — Disable auto-appending to content and use the shortcode instead.
* **Accessibility** — Each card is a single link, with keyboard focus styles, Load More busy state, and a screen-reader live region.
* **Fully Sanitized & Escaped** — Built with WordPress security best practices throughout.

= Shortcode Usage =

Basic usage:
`[zyonrp_related_posts]`

With options:
`[zyonrp_related_posts count="3" layout="list" title="You May Also Like"]`

= Requirements =
* WordPress 5.0+
* PHP 7.4+

== Installation ==

1. Upload the `zyonix-related-posts` folder to the `/wp-content/plugins/` directory, or install the plugin through the WordPress plugins screen directly.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Go to **Settings → Related Posts** to configure the plugin.
4. That's it! Related posts will now appear automatically after your post content.

== Frequently Asked Questions ==

= Related posts are not showing up. What should I do? =

Go to **Settings → Related Posts** and make sure:
1. The current post type is checked under "Show Related Posts On" if you rely on auto-append.
2. "Query Related Posts From" includes the types you want as results.
3. At least one matching source can apply: Category, Tag, Author, or a custom taxonomy with terms on the current post.
4. "Auto-append to Content" is enabled — or place the `[zyonrp_related_posts]` shortcode / widget instead.

= What is the difference between Show On and Query From? =

**Show Related Posts On** controls which singular post types automatically insert the related posts section after content.

**Query Related Posts From** controls which post types can appear as related results.

The shortcode and widget do not consult "Show Related Posts On". They still only return posts from "Query Related Posts From".

= How does matching work? =

Category, tag, and enabled custom taxonomies are combined with **OR** (a post is related if it shares any of those). Author matching is optional and applied as **AND** when enabled.

= Can I show related posts manually instead of automatically? =

Yes. Disable "Auto-append to Content" in the settings, then place the shortcode `[zyonrp_related_posts]` or the Related Posts widget wherever you want them to appear.

= Can I style the related posts section myself? =

Yes. Add styles to your theme's stylesheet targeting `.zyonrp-related-posts`.

= Does it support custom post types? =

Yes. Public post types appear under both "Show Related Posts On" and "Query Related Posts From".

= Does it support custom taxonomies? =

Yes. Public, queryable custom taxonomies attached to your Query From post types can be enabled under Matching Logic. Category and tag matching stay separate.

= What does the shortcode support? =

`[zyonrp_related_posts count="5" layout="grid" title="Related Posts"]`

All three attributes are optional and fall back to your global settings.

== Screenshots ==

1. The related posts section displayed on a post — Grid layout.
2. List layout with excerpt, date, and read time enabled.
3. The Settings page — Display Settings panel.
4. The Settings page — Content & Meta toggles.
5. The Settings page — Matching Logic panel.

== Changelog ==

= 1.0.6 =
* Renamed the plugin to “Related Posts by Zyonix Digital”.
* Preserved existing internal APIs, settings, shortcode, AJAX action, cache, and compatibility.

= 1.0.5 =
* Documented Show On vs Query From, custom taxonomy matching, relevance ranking, and ID caching in the readme.
* Load More now rejects oversized signed-state (`cfg`) payloads before JSON decode.
* Split "Show Related Posts On" from "Query Related Posts From" (existing `zyonrp_post_types` still works until settings are saved).
* Optional matching on public custom taxonomies, combined with category/tag using OR.
* New Relevance order: shared terms, overlap, and post type, with Load More over the ranked pool.
* Related IDs are cached in transients (not HTML); cache salt updates when published posts or matching terms change.
* Thumbnail meta is primed after ID hydration to avoid extra queries.

= 1.0.4 =
* Load More now uses the same query contract as the first render, including shortcode count/layout/title overrides.
* Random + Load More continues from a seeded result pool and no longer switches to date order or repeats posts.
* Already displayed posts are excluded on the server, not only in the browser.
* Load More counts new items from the AJAX response instead of temporary DOM classes.
* Widget output no longer runs plugin HTML through wp_kses_post, which could strip the Load More button.
* Related post cards use a single link for accessibility.
* Excerpt ellipsis no longer renders as a literal HTML entity.
* Frontend CSS/JS load only when related posts can render; JS loads only when Load More is enabled.
* Load More button exposes busy/live-region state and restores its label after errors.
* Auto-append no longer duplicates when page builders re-run the_content or the shortcode is already present.
* Settings screen shows a success notice after save.

= 1.0.3 =
* Critical fix: replaced get_the_excerpt() with direct post_excerpt/post_content reading to prevent the_content filter chain firing on every related post item — the root cause of page load blocking.
* Fix: post meta cache re-enabled so has_post_thumbnail() and get_the_post_thumbnail() do not fire individual DB queries per post.
* Fix: post_content_cache now built for both read_time and excerpt, not just read_time.

= 1.0.2 =
* Performance fix: plugin no longer runs an unrestricted WP_Query when a post has no category/tag assigned, which caused slowdowns on large sites.
* Performance fix: added update_post_meta_cache and update_post_term_cache=false to avoid unnecessary DB queries.
* Performance fix: permalink now cached per post item instead of fetched twice.

= 1.0.1 =
* Fixed Load More "has_more" logic that caused the button to never hide.
* Security: validate post status and password protection in AJAX handler.
* Performance: PHP shuffle pool fetch avoids ORDER BY RAND() full table scan.
* Performance: post content cache avoids N+1 DB queries for read-time calculation.
* Security: post types validated against registered public types on every request.

= 1.0.0 =
* Initial release.
* Grid and List layout options.
* Excerpt, publish date, and estimated read time display options.
* AJAX-powered "Load More" button.
* Shortcode `[zyonrp_related_posts]` with count, layout, and title attributes.
* WordPress Widget support.
* Order By option (Latest, Most Commented, Random).
* Thumbnail size selector.
* Open links in new tab option.
* Auto-append to content toggle.
* Default options set on plugin activation.
* Full input sanitization, validation, and escaping per WordPress coding standards.

== Upgrade Notice ==

= 1.0.6 =
Renames the plugin to “Related Posts by Zyonix Digital”. Existing settings, shortcode, and Load More continue to work with no migration.

= 1.0.5 =
Adds Query From vs Show On, custom taxonomy matching, relevance ordering, and ID caching. Existing settings keep working without opening the settings screen.

= 1.0.0 =
Initial release.
