=== Custom FAQ ===
Contributors: limekiln
Tags: faq, accordion, faqpage, schema, jsonld, details, repeater
Requires at least: 5.8
Tested up to: 6.5
Requires PHP: 7.4
Stable tag: 2.4.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A lightweight FAQ manager built around FAQ Groups with a repeater of Q/A pairs. Native <details>/<summary>, clean semantic HTML, FAQPage JSON-LD schema, no bloat.

== Description ==

Custom FAQ is a small WordPress plugin that lets you manage FAQs as **Groups** in the admin and embed them with a single shortcode. Each group (e.g. "Venue Questions", "Wedding Questions") contains a repeater of Question/Answer pairs — no separate WordPress post per FAQ item, just one tidy edit screen per topic.

It outputs accessible, semantic HTML using native `<details>` / `<summary>` accordions and emits valid `FAQPage` JSON-LD structured data so the answers are eligible for rich results on search engines.

It is intentionally minimal:

*   One custom post type (`faq_group`) — **one post per group**, not per question.
*   Questions and answers live inside each group as a repeater field (post meta).
*   One shortcode (`[custom_faq]`) for the front-end.
*   Tiny CSS that only structures the markup — your theme's typography, colour, spacing, etc. take over.
*   No jQuery on the front-end. No third-party libraries. No page-builder dependencies.
*   FAQ CSS / JS only load on pages where the shortcode is actually used.

= Features =

*   **FAQ Groups** — create topical groups (Venue Questions, Local Area Questions, …). Each group is one admin screen.
*   **Repeater UI** — add unlimited FAQs to a group with a clean "Add FAQ" button, drag-to-reorder rows, and per-row delete.
*   **Prominent shortcode banner** — every group's edit screen shows its shortcode directly under the title with a Copy button and a "Saved" confirmation after each update.
*   **Per-group "Show group name on front-end" toggle** — hide a group's heading without editing the shortcode (useful when the host page already has its own heading).
*   **Settings page** — global options for capitalising questions, unifying the question + answer font family, custom question / answer font sizes, and the spacing between a question and its answer.
*   **Single-group mode** — `[custom_faq topic="venue"]` displays only that group.
*   **All-groups mode** — `[custom_faq]` displays every group, each with its own heading.
*   **Group ordering** — drag-and-drop groups in the admin list table; the front-end follows.
*   **Expand / collapse all** — opt-in pair of buttons via `toggle="1"`.
*   **Heading level option** — `heading="h2"` (default) through `heading="h6"`.
*   **Schema.org FAQPage** — automatically generated for every FAQ actually rendered on the page.
*   **Theme-first styling** — uses `currentColor`, `em` units, and avoids font/colour overrides so the FAQ blends in with whatever theme you're using.

== Installation ==

1. Upload the `custom-faq` folder to `/wp-content/plugins/`.
2. Activate the plugin via the **Plugins** screen.
3. Go to **Custom FAQ → Add New Group** and create your first group (e.g. "Venue Questions").
4. Use the **FAQ Items** meta box to add as many Q/A rows as you like, drag to reorder, and Save.
5. Drop the shortcode on any page:

   `[custom_faq]` — every group, with headings
   `[custom_faq topic="venue-questions"]` — just that one group

The "Shortcode" side meta box on each group's edit screen shows the exact shortcode (with a Copy button).

== Shortcode reference ==

`[custom_faq]`

| Attribute        | Default      | Values                                  | Notes                                                                                                              |
|------------------|--------------|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| `topic`          | _empty_      | slug, name, or post ID                  | If set, only that group's FAQs render. If empty, every group with FAQs is rendered, each with its own heading.     |
| `heading`        | `auto`       | `auto` &#124; `h2` &#124; `h3` &#124; `h4` &#124; `h5` &#124; `h6` | `auto` honours the global Heading level setting; an explicit `h2`–`h6` overrides it per-shortcode.                 |
| `show_heading`   | `auto`       | `auto` &#124; `1` &#124; `0`            | `auto` honours each group's "Show group name on front-end" toggle. `1` / `0` override per-shortcode.               |
| `toggle`         | `0`          | `1` &#124; `0`                          | Show the "Expand all" / "Collapse all" buttons.                                                                    |
| `open`           | `0`          | `1` &#124; `0`                          | Open the first FAQ by default.                                                                                     |

The `topic` value accepts the post ID, slug, exact title, or a case-insensitive title — so `topic="Venue Questions"` works the same as `topic="venue-questions"`.

== Markup it outputs ==

`
<section class="cfaq-topic cfaq-topic-venue-questions" id="cfaq-topic-venue-questions-…">
    <h2 class="cfaq-topic-title">Venue Questions</h2>

    <div class="cfaq-items">
        <details class="cfaq-item" id="cfaq-item-venue-questions-1">
            <summary class="cfaq-question">Do you host weddings?</summary>
            <div class="cfaq-answer">
                <p>Yes, we host weddings year-round…</p>
            </div>
        </details>
        …
    </div>
</section>
`

Plus a single `<script type="application/ld+json" class="cfaq-schema">…</script>` in the page footer that lists every FAQ rendered on the current request as a `FAQPage`.

== Frequently Asked Questions ==

= How is this different from "one FAQ = one post" plugins? =

In Custom FAQ each **group** is one WordPress post. The individual questions and answers live inside that post as repeater rows (post meta). Editing a group means scrolling one screen of Q/A rows — no jumping between dozens of individual posts.

= I'm upgrading from v1.x — what happens to my old FAQs? =

v1.x stored each FAQ as a `faq_item` post with `faq_topic` terms. v2.x switches to a `faq_group` post type with a repeater of items. **Old `faq_item` posts are not automatically migrated**; they're left in the database but no longer surface. If you have v1 content to keep, copy/paste the questions and answers into the new repeater on a fresh group, then deactivate v1.

= Does it work with page builders / block themes? =

Yes — it's just a shortcode. Drop it into a paragraph or a shortcode block. The plugin doesn't depend on any page builder or block library.

= Will it conflict with another FAQ plugin's schema? =

If another plugin is also emitting `FAQPage` schema for the same questions, that can confuse search engines. Deactivate the other plugin's schema output on pages where Custom FAQ runs.

= Does it use jQuery? =

Only in the admin (for the repeater drag-drop, which uses WordPress's bundled jQuery UI Sortable). The front-end is pure vanilla JS — and only loads when `toggle="1"` is on the shortcode.

== Settings ==

**Custom FAQ → Settings** is split into four sections.

= Topic title =

*   **Show topic title** — global default for whether a group's name renders above its FAQs. Each group's edit screen can override this individually.
*   **Heading level** — H2..H6 tag used for group titles. Defaults to H2; drop to H3/H4 when the FAQ sits inside a larger page that already has its own H2.
*   **Title alignment** — Default / Left / Center / Right.
*   **Nested layout** — indent the FAQs slightly under the title. Pure margin-only, no visible frame.

= Questions =

*   **Capitalise questions** — CSS `text-transform: capitalize` on every question.
*   **Question font size** — any CSS length (`1.15em`, `18px`, `1rem`, `120%`). Blank inherits from the theme.

= Answers =

*   **Answer font size** — same shape as above. When set it overrides theme paragraph styling.
*   **Answer text alignment** — Default / Left / Center / Right / Justify.
*   **Unify question / answer font** — forces the answer to inherit the question's font family. Turn this on if your theme styles `<summary>` and `<p>` with different fonts.

= Layout =

*   **Space between question and answer** — gap between the question and the opened answer. Default `0.75em`.

When a setting is non-default, the plugin emits scoped `!important` rules so its own styling wins against theme rules like `.entry-content p { font-size: 18px }`. Blank settings stay as `inherit` and let the theme keep control.

The settings are applied with one inline `<style>` tag emitted only on pages that actually render the shortcode — no global stylesheet bloat.

== Per-group options ==

Each FAQ Group's edit screen has a "Display options" side meta box with a single tri-state dropdown:

*   **Use default (Show / Hide)** — follow the global "Show topic title" setting.
*   **Always show** — force this group's title on.
*   **Always hide** — force this group's title off.

The shortcode attribute `show_heading` defaults to `auto`, which honours the dropdown above. Pass `show_heading="1"` or `show_heading="0"` to override per-shortcode.

The `heading` shortcode attribute defaults to `auto` too — it picks up the global Heading level setting unless you pass `heading="h3"` (or any of `h2`–`h6`) explicitly.

== Changelog ==

= 2.4.1 =
*   "Capitalise questions" and "Capitalise answers" now display the text in ALL CAPS (CSS `text-transform: uppercase`) rather than just title-casing each word. Setting names are unchanged so existing toggles keep working.

= 2.4.0 =
*   New **Capitalise answers** setting in the Answers section. Same approach as Capitalise questions — applies `text-transform: capitalize` to every answer body.
*   Capitalise questions now wins reliably against theme rules: selectors are prefixed with `html body` so the resulting specificity beats common theme patterns like `.entry-content summary *`.

= 2.3.4 =
*   Fixed: clicking to expand one FAQ no longer pushes the next FAQ to the right. The answer body now establishes its own block formatting context (`display: flow-root`) so theme-styled floats inside the answer can't leak out, and `<details>` items (both closed and `[open]`) are locked to `display: block`, `clear: both`, no float / transform / sideways padding.

= 2.3.3 =
*   Title-on layout fix: FAQ sections now get explicit `cfaq-has-title` / `cfaq-no-title` classes, the title is hard-reset to a plain cleared block, and the FAQ items clear the title before rendering. This prevents theme heading styles from pushing the first question to the right when the topic title is visible.
*   Nested layout indent now only applies when the title is visible and has been reduced from `1.5em` to `0.75em`.

= 2.3.2 =
*   Theme-conflict resets: explicitly neutralise theme `summary::before` / `::after` arrows and force the question summary's flex direction, alignment, padding, margin, and text-indent. Stops themes that paint their own accordion chevrons or push `<summary>` text right with `padding-left` / `text-indent` from leaking through.
*   Also resets `<section.cfaq-topic>` and `<div.cfaq-items>` padding/background so themes can't paint a card or offset the inner content.

= 2.3.1 =
*   Nested layout no longer draws a vertical guide on the left. The previous border combined with the top/bottom borders already on each FAQ item created a three-sided frame that looked like a "window" surrounding the section. The setting now applies a clean margin-left indent only.

= 2.3.0 =
*   New **Topic title** settings: global default "Show topic title", **Heading level** (H2..H6), **Title alignment** (Default / Left / Center / Right), and **Nested layout** (indent FAQs under the title with a subtle vertical guide).
*   Per-group "Show group name on the front-end" is now a **tri-state dropdown**: *Use default*, *Always show*, *Always hide*. The "Use default" option follows the new global setting.
*   The `heading` shortcode attribute now defaults to `auto` and reads the global Heading level setting; explicit `h2`–`h6` still overrides per-shortcode.
*   Settings page reorganised into four sections (Topic title, Questions, Answers, Layout) for easier scanning.

= 2.2.0 =
*   New **Answer text alignment** setting (Default / Left / Center / Right / Justify).
*   Plugin now wins decisively against theme paragraph styling — font size, alignment, and font family settings apply with `!important` scoped to `.cfaq-topic`. Blank settings still inherit from the theme.
*   Question summary is now a flex container with a dedicated `+` icon span on the right, so long questions can never collide with the icon.
*   The `+` icon hides cleanly when an answer is expanded (was previously swapping to `−`). Space is reserved so the question text doesn't reflow on toggle.

= 2.1.0 =
*   New **Settings** screen under Custom FAQ → Settings: capitalise questions, unify question + answer font family, question/answer font size, and question→answer spacing.
*   Per-group **"Show group name on the front-end"** toggle (defaults to on for upgraders).
*   Prominent **shortcode banner** under each group's title with a Copy button; banner highlights green on save.
*   Removed the old narrow "Shortcode" side meta box (folded into the banner).
*   Increased default spacing between question and answer; CSS variables make it tunable from Settings.
*   `show_heading` shortcode attribute now defaults to `auto` and respects each group's toggle. Explicit `1` / `0` still works as a per-shortcode override.

= 2.0.0 =
*   **Architecture change**: FAQs are now organised as **FAQ Groups** containing a repeater of question/answer pairs, instead of one WordPress post per FAQ item. The `faq_topic` taxonomy has been removed; group posts replace topic terms.
*   New repeater meta box: add, drag-to-reorder, and delete FAQ items inline on the group edit screen.
*   New "Shortcode" side meta box with copy-to-clipboard for the group's shortcode.
*   List table now shows a count of FAQs per group and supports drag-to-reorder of groups themselves.
*   FAQPage schema now de-duplicates identical Q/A pairs across multiple shortcodes on the same page.

= 1.0.0 =
*   Initial release.
