=== WT Catalog ===
Contributors: wijntransport
Tags: wine, beer, catalog, b2b, product listing
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.0.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Your WT wine and beer catalog, live on your own website.

== Description ==

WT (Wijntransport B.V.) supplies wine and beer to restaurants, hotels, shops and wholesalers. This
plugin puts that assortment on your own WordPress website: a wine listing, a beer listing and a
page per product, filled straight from WT's catalog every time a visitor looks at them. Nothing is
copied into your site and kept there, so a product that changes at WT changes on your website too.

**Who it is for.** WT customers who have a WordPress website. You need an API URL and an API key
from WT; without them the plugin has nothing to show. Ask your WT contact for both. There is no
free or public catalog behind this plugin.

**What a visitor gets.** A listing of your assortment with a picture, a name, the alcohol
percentage, the colour, the bottle size and the case quantity for every product. Down the side (or
behind a "Filters" button on a phone) are filters for country, colour, bottle size and producer,
each showing how many products are behind it, plus a search box. Ticking a filter narrows the list
and the other filters' counts immediately. The filters need JavaScript in the visitor's browser;
the search box is an ordinary form and works without it. Clicking a product opens its own page
with the producer's own name for it, the region it comes from, its rating, badges such as ORGANIC
or NEW, the tasting note, the food pairing, and the specifications split into "Characteristics"
and "Bottle".

**No prices, anywhere.** WT's prices are per customer and are not part of what this plugin shows.
No price is displayed, and none is stored on your site.

**What you control.** Two things, both under **WT** in the WordPress admin menu:

* Which products are hidden. See "Blocked products" below.
* Which slice of the catalog each listing shows: everything WT sells, or only what you have
  actually bought in the last 3, 6 or 12 months, or ever. Wine and beer are set separately, so you
  can show every wine but only the beers you stock.

= External services =

This plugin depends on one external service: the **WT catalog API**. It is the source of every
product, picture, filter and piece of text the plugin displays. Your site has no catalog of its
own.

**Where it connects.** To the address you enter yourself under WT → Settings ("API URL"). The
plugin ships no address of its own; you receive the URL and the key together from WT.

**What is sent, and when.** Every request carries your API key, so the service knows which
customer's assortment to answer with. A request is made when a visitor opens a listing or a
product page and the plugin has no fresh copy of it, and once a day to rebuild the product index.
Along with the key the plugin sends only what the visitor asked for: the page number, the search
term they typed, the filters they ticked (country, colour, bottle size, producer), which drink the
page is for, your purchase-history setting, and the identifier of the product being viewed. **No
personal data of your visitors is sent** — no name, e-mail address, IP address, cookie or user
account is forwarded, and the plugin sets no cookies of its own.

**What is stored on your site.** One settings row holding your API URL, your API key, your two
purchase-history choices and your block list; a small index of the catalog (identifier, base
number, link, name, vintage, drink, thumbnail) used to build product addresses and the XML
sitemap; and short-lived cached copies of listing and product responses. **No price is ever
requested for display, shown or stored.** Deleting the plugin from Plugins → Installed Plugins
removes all of it, including your API key.

**Terms and privacy.** The catalog is a service of WT for its own customers, and its use is
governed by your customer agreement with WT. Nothing about your website's visitors is sent to it —
see above — so no visitor-facing privacy policy applies to the plugin's requests. Company site:
https://wt.group/

= The screens, one by one =

**The wine listing** (screenshot 1) is an ordinary WordPress page to which you gave the page
template "[WT] Wine listing". The plugin fills it: search box, the filter panel, the result count,
the grid of products and the pager. Every filter choice is in the page's own address, so a
filtered list can be bookmarked, shared and linked to. Filter labels — country names, colour names
— come from WT in the language attached to your key, which is why they may read Dutch on an
English site.

**The beer listing** is the same page, with the page template "[WT] Beer listing" instead. It
shows beer only, has its own purchase-history setting and its own search. You only need it if you
sell beer.

**The product page** (screenshot 2) lives under whichever listing the visitor came from —
`/wines/product/1015-chat-maucoil-chateauneuf-du-pape-rouge-bio/`. You do not create these pages;
the plugin answers those addresses itself. Text blocks that WT has not filled in are left out
rather than shown empty, and the specification rows differ per drink: closure type, vintage and
colour are wine rows, degrees Plato is a beer row.

**On a phone** (screenshot 3) the filter panel folds into a "Filters" button above the results,
with the number of active filters on it. Opening it shows the same filter sections; each opens on
a tap.

**WT → Settings** (screenshot 4) is where the API URL and the API key go, and where you choose the
purchase-history filter per listing. Underneath is a status panel: which URL is in use and whether
a key is saved, how many products are in the index and when it was last built, which SEO plugin is
providing meta tags and the sitemap, which pages are acting as your wine and beer listings, and
how many products you have blocked. Two buttons sit below it: **Rebuild product index now**, which
fetches the whole catalog again, and **Flush cache**, which throws away the pages the plugin is
remembering. Saving a key checks it against the catalog before storing it, and tells you if it was
refused; a refused key never replaces the saved one.

**WT → Blocked products** (screenshot 5) is a search box. Type a product name or a base number,
and every match comes back with its base number, name, drink and vintages. "Block" hides that
product from the listing, from its own product page and from the sitemap — every vintage of it,
because blocking works on the base number. The "Blocked" tab lists what you have hidden, and
unblocks it again.

== Installation ==

1. In the WordPress admin, go to **Plugins → Add New → Upload Plugin**, choose the plugin's zip
   file, click **Install Now** and then **Activate**.
2. Go to **WT → Settings**. Paste the **API URL** and the **API key** you received from WT and
   click **Save Changes**. The key is checked against the catalog while you save; if it is refused
   you are told so and nothing is stored.
3. Go to **Pages → Add New**, give the page a title such as "Wines", and under **Page Attributes →
   Template** choose **[WT] Wine listing**. Publish it.
4. If you also sell beer, create a second page the same way and choose **[WT] Beer listing** for
   it.
5. Wait for the first product index to be built. It starts by itself a few seconds after the key
   is saved and takes a few minutes for a large assortment; the **Product index** row on the
   settings screen shows the number of products and the time it finished. If it still says "not
   built yet" after that, press **Rebuild product index now**.
6. Open the listing page. If it is empty, the settings screen's status panel says why.

= Upgrading from version 1.x =

Read this before you update; 2.0.0 is not a drop-in replacement.

* **The address changes; your key does not.** Version 1.x talked to an address built into the
  plugin. 2.0.0 talks to a new catalog service at a new address: enter the **API URL** you receive
  from WT under WT → Settings. **Your existing API key stays valid** and is kept through the
  update. Until the URL is entered the listing stays empty.
* **Product addresses have changed.** 1.x used `/<your-listing-page>/wine/<name>/`. 2.0.0 uses
  `/<your-listing-page>/product/<base number>-<name>/`. **Old addresses are not redirected** —
  they return "not found". If you have linked to individual wines from menus, posts or
  newsletters, those links need updating. Search engines pick the new addresses up from the
  sitemap.
* **The wine page now shows wine only.** In 1.x one page showed everything. If you sell beer,
  create a second page with the "[WT] Beer listing" template, or your beers disappear.
* **Your existing settings are kept.** Your API key, the block list, and the single
  purchase-history setting from 1.x all survive; the purchase-history setting is copied to both
  the wine and the beer listing, where you can then change them independently.
* **WordPress 6.7 and PHP 7.4** are the minimum. On anything older, do not update.

== Frequently Asked Questions ==

= How do I hide a product? =

WT → Blocked products. Search for it by name, or type its base number, and press "Block". Blocking
works on the base number, so **every vintage of that product** is hidden at once — from the
listing, from its own product page (which then returns "not found") and from the XML sitemap. The
"Blocked" tab lists everything you have hidden and unblocks it again. You can also block a base
number the plugin has not indexed yet, using the "Block by base number" box; a number the catalog
does not know is refused rather than blocked.

= Why does my beer page show wine, or nothing at all? =

Check the page's template under Page Attributes. "[WT] Wine listing" shows wine only and "[WT]
Beer listing" shows beer only — a page with the wrong one shows the wrong drink. If a
correctly-templated beer page is empty, look at WT → Settings: if "Beer listing shows…" is set to
a purchase-history window and you have not bought beer in that window, there is nothing to show.
Set it to "All products" to check.

= Why does the listing show fewer products than WT's catalog? =

Two settings can do that, and they add up:

* **The purchase-history filter** (WT → Settings). If a listing is set to "Products purchased in
  the last 12 months" it shows only what you bought in that period, not the whole assortment. "All
  products" removes the restriction.
* **Blocked products.** Everything on that list is hidden.

If neither explains it, press "Rebuild product index now" and check the status panel for an error.

= Can I change the look? =

Yes — with CSS in your theme or in Appearance → Customise → Additional CSS. The plugin's markup
uses stable class names that will not change without a major version:

* Listing: `.wt-listing`, `.wt-listing--wine`, `.wt-listing--beer`, `.cc-search-box`, `.wt-empty`,
  `.wt-error`
* Filters: `.cc-sidebar`, `.cc-sidebar__section`, `.cc-sidebar__title`, `.cc-sidebar__reset`,
  `.cc-filter-bar`, `.cc-filter-bar__button`, `.cc__filter-item`, `.cc__filter-text`,
  `.cc__filter-count`
* Results: `.cc-product`, `.cc-product__image`, `.cc-product__title`, `.cc-product__info`,
  `.cc-stats`, `.cc-pagination`
* Product page: `.wt-single`, `.wt-product__head`, `.wt-product__origin`, `.wt-product__marks`,
  `.wt-product__body`, `.wt-product__col--prose`, `.wt-product__col--specs`, `.wt-specs`,
  `.wt-specs__group`, `.wt-rating`, `.wt-badge`, `.wt-breadcrumb`

Class names beginning `js-` drive the plugin's own JavaScript. Do not style or remove them.

= Why is a product missing that WT added today? =

The product index is rebuilt once a day, and listing pages are remembered for a few minutes at a
time. Press **Rebuild product index now** on the settings screen to pull the catalog again
immediately, and **Flush cache** to drop the remembered pages. Both are safe to press at any time.

= Does it work with Yoast SEO or Rank Math? =

Yes. If Yoast SEO or Rank Math is active, the plugin hands it the title, description, canonical
address, Open Graph tags and the products for its XML sitemap, so your products appear in the
sitemap you already have. With neither installed, WordPress's own sitemap and meta tags are used
instead. Nothing needs configuring either way; the settings screen's **SEO** row names which
plugin is doing which job.

= Which languages does it speak? =

The plugin's own text — buttons, headings, filter section names, the admin screens — is available
in Dutch, German and English, and follows your site's language setting. The **product text** and
the **filter values** (country and colour names) come from WT in the language attached to your API
key, and are not translated by the plugin. So an English-language site with a Dutch-language key
shows English buttons and Dutch country names. If that is wrong for you, ask WT to change the
language on your key.

= Do I need to do anything about permalinks? =

Only if product pages return "not found" right after activating. Then go to Settings → Permalinks
and press "Save Changes" once, without changing anything.

= What happens if the catalog is unreachable, or my key is refused? =

Either way the listing says so on the page rather than showing an empty list and passing that off
as your assortment. The HTTP status differs on purpose:

* **Catalog unreachable, or rate-limiting you** — HTTP 503 with a Retry-After header, so search
  engines come back later instead of dropping the page.
* **API key refused, or no key entered yet** — HTTP 200 with the message on the page. This one is
  for you, not for a search engine: it has to be visible so whoever looks at the site can go and
  fix the key.
* **A product that does not exist, or that you have blocked** — a genuine HTTP 404.

= What is removed when I delete the plugin? =

Everything the plugin wrote: the settings row (including your API key), the block list, the
product index, every cached page and the daily scheduled task. That happens on **delete**, from
Plugins → Installed Plugins.

Deactivating loses no data, but it is not nothing either: it cancels the daily index rebuild and
removes the product-page address rule from WordPress's list, so `/product/…` addresses stop
resolving while the plugin is off. Activating it again puts both back, and your settings, block
list and index are exactly as you left them.

== Screenshots ==

1. The wine listing with the filter panel open and France ticked: 361 French wines, each filter
   value showing how many products are behind it. Country and colour names come from WT in the
   language attached to the key, which is Dutch here.
2. A product page: name, the producer's own name for it, country, region and appellation, the
   Vivino rating with its number of ratings, an ORGANIC badge, the bottle picture, the
   vinification and tasting notes and the food pairing, and the specifications grouped into
   Characteristics and Bottle. No price anywhere.
3. The same wine listing on a phone: the "Filters (2)" bar open above the results, with the
   Country and Colour sections expanded and France and Red ticked.
4. WT → Settings: the API URL and key, the purchase-history filter for the wine and the beer
   listing side by side, and the status panel showing the index, the SEO integration, the two
   listing pages and the number of blocked products.
5. WT → Blocked products: a search for "Maucoil" returning two products, one of them already
   blocked and marked as such.

== Changelog ==

= 2.0.0 =
Release Date: September 2026

A full rewrite against WT's new catalog service.

**Breaking changes.** This release does not work with a 1.x installation as it stands. 2.0.0 talks
to a new catalog service at a new address: enter the **API URL** you receive from WT under WT →
Settings before anything is shown. **Your existing API key stays valid** and is kept through the
update. **Product addresses have changed** from `/<listing>/wine/<name>/` to
`/<listing>/product/<base number>-<name>/`, and the old addresses are **not redirected** — links
to individual wines from elsewhere on your site need updating. The wine listing now shows **wine
only**, so a site that also sells beer needs a second page using the new "[WT] Beer listing"
template. The minimum requirements rise to **WordPress 6.7 and PHP 7.4**.

* Rewritten data layer against the new catalog API; no product data is kept on your site beyond a
  small index used for links and the sitemap.
* Beer and wine on separate pages, via the existing "[WT] Wine listing" template and the new "[WT]
  Beer listing" template.
* Live filters on country, colour, bottle size and producer, with a count on every value that
  narrows as you tick others, plus a producer type-to-filter box and a search box. Ticking a
  filter updates the results without reloading the page. The filters require JavaScript; the
  search box is a plain form and works without it.
* Filters, search and page number are part of the page address, so a filtered listing can be
  bookmarked, shared and linked to.
* Rewritten product page: name, the producer's own name, country/region/appellation, rating with
  its source and number of ratings, ORGANIC / NEW / VEGAN badges, tasting notes and food pairing
  shown only when they carry text, and specifications grouped into Characteristics and Bottle with
  the rows appropriate to wine or to beer.
* Blocked products are blocked by base number, so every vintage of a product is hidden at once,
  from the listing, the product page and the sitemap. The screen searches by name or by base
  number and can block a number the index has not seen yet.
* Purchase-history filter per listing — all products, or those purchased in the last 3, 6 or 12
  months, or ever purchased — set independently for wine and for beer.
* Yoast SEO, Rank Math and WordPress core integrations for the XML sitemap, canonical addresses,
  titles, descriptions, Open Graph tags and rel prev/next; the right one is chosen automatically.
* A real error state instead of an empty listing that looks like an empty assortment. A catalog
  that cannot be reached, or that is rate-limiting, answers HTTP 503 with a Retry-After header so
  search engines come back later. A refused or missing API key answers HTTP 200 on purpose: it is
  the site operator who has to read that message, and a 503 would hide it from them and from
  search engines alike. An unknown product returns a genuine 404.
* API key and URL are settings, checked against the catalog when saved; the plugin ships no
  address of its own. The URL can be fixed in `wp-config.php` with
  `define( 'WIJNTRANSPORT_API_URL', '…' );`.
* Dutch, German and English translations of the plugin's own text.
* Deleting the plugin now removes everything it wrote, including the API key. In 1.x the key was
  left behind for ever.
* Responsive listing: the filter panel folds into a "Filters" bar below 901 pixels wide.

= 1.4.1 =
Release Date: April 12, 2021

* Update api url

= 1.4.0 =
Release Date: December 15, 2020

* Generate sitemap with wines for yoast seo

= 1.3.0 =
Release Date: October 15, 2020

* Add vintage to single wine
* Add seo head links: canonical, prev, next

= 1.2.0 =
Release Date: September 17, 2020

* Update translation
* Update styles

= 1.1.0 =
Release Date: September 16, 2020

* Update placeholder image
* Fix translation
* Styles fixes

= 1.0.0 =
Release Date: August 20, 2020

* Initial release

== Upgrade Notice ==

= 2.0.0 =
2.0.0 talks to a new catalog service at a new address: enter the API URL you receive from WT under
WT → Settings. Your existing API key stays valid and is kept through the update. The listing stays
empty until the URL is in. Old /wine/ links are not redirected; beer needs its own page.
