=== Ethan's Taxonomy SEO ===
Contributors: Ethan J. Hulbert
Tags: seo, categories, tags, taxonomy, meta
Requires at least: 5.7
Tested up to: 6.6
Stable tag: 2.0.0
License: GPLv2 or later

Adds Title Tag, Meta Description, Canonical Link, Robots (NOINDEX/NOFOLLOW),
Body Class, and raw custom <head> HTML fields to the Add/Edit Category and
Add/Edit Tag admin screens, with frontend output designed to replace — not
duplicate — whatever WordPress core or another SEO plugin (Yoast, AIOSEO,
Rank Math, SEOPress, etc.) would otherwise output on that same page.

== Installation ==

1. Upload the `ethans-taxonomy-seo` folder to `/wp-content/plugins/`.
2. Activate the plugin through the "Plugins" menu.
3. Go to Posts → Categories (or Posts → Tags) and either add a new term or
   edit an existing one — the new fields appear below the built-in
   Description field.
4. Optional: visit Settings → Ethan's Taxonomy SEO to see which other SEO
   plugins (if any) were detected, and to adjust the two toggles described
   below.

== How replacement works, per field ==

- **Title tag** — WordPress funnels every document title through a single
  filter chain (`pre_get_document_title`). This plugin hooks in at the
  very last possible priority, so its override always wins outright.
  There's no possibility of a duplicate `<title>` tag.
- **Robots** — Since WP 5.7, robots directives from every source are
  collected through a single `wp_robots` filter into one merged tag. This
  plugin adds its directives there, same as current versions of Yoast /
  Rank Math / AIOSEO / SEOPress. (A very old version of another plugin
  that still echoes its own raw `<meta name="robots">` tag, bypassing
  `wp_robots`, is a known edge case this doesn't cover.)
- **Meta description & canonical link** — the two fields with no shared
  hook in WordPress to rely on. When **Force Override** is on (the
  default) and a term actually has one of these set, the plugin buffers
  everything the `wp_head` action outputs — including another plugin's —
  strips out any existing `<meta name="description">` / `<link
  rel="canonical">` tag it finds, and appends its own value in place.
  Buffering only runs on pages where there's actually something to
  replace. Turning Force Override off falls back to simply adding the tag
  without touching whatever else is there, which is occasionally useful
  for comparing behavior side-by-side.
- **Body class** and **custom `<head>` HTML** are pure additions in both
  modes — there's nothing to replace for either.

== Settings (Settings → Ethan's Taxonomy SEO) ==

- **Detected SEO plugins** — informational list of any other recognized
  SEO plugin currently active, so it's always clear at a glance what else
  is in play.
- **Force Override** — see above. On by default.
- **Debug Comment** — inserts one HTML comment near the end of `<head>` on
  managed term archive pages, summarizing exactly what fired: which
  fields matched, whether an existing description/canonical tag was found
  and stripped, and what other SEO plugins were detected. Visible only in
  view-source, never to visitors.

== Other notes ==

- All values are stored as term meta (`wp_termmeta`) — no custom database
  table.
- The Custom `<head>` HTML field is saved unescaped only for users with
  the `unfiltered_html` capability (Administrators, on a typical
  single-site install). Other roles have it passed through
  `wp_kses_post()`, which strips tags like `<script>` and `<meta>`.
- The Title Tag and Meta Description fields show a live character count
  as you type — a raw count only, no limit is flagged and nothing changes
  color at any length.
- The Categories / Tags list tables gain a small "SEO" column with a
  checkmark on any term that has at least one override set.
- Currently manages the two core taxonomies, `category` and `post_tag`.
  Add a custom taxonomy via the `etseo_managed_taxonomies` filter.
- Known edge case: if a theme hardcodes its own `<title>` tag directly in
  header.php rather than relying on `wp_head` / theme-support for
  title-tag (rare in any theme built since ~2015), the title filter still
  overrides `wp_get_document_title()`'s return value correctly, but a
  theme that doesn't call that function at all is outside what any
  title-tag plugin can control.
