=== Cloudline Product Catalogue ===
Contributors: cloudline-tech
Tags: product catalogue, product showcase, whatsapp, b2b, woocommerce-free
Requires at least: 5.8
Requires PHP: 7.4
Tested up to: 6.6
Stable tag: 4.0.0
License: GPL-2.0-or-later

A lightweight, WooCommerce-free product catalogue for businesses that want product discovery and enquiries, not a shopping cart.

== What stays in the core ==

* Product management, categories, brands, search and filters
* Product pages, featured image and gallery
* Dynamic product specifications
* Product relationships: related, accessories, compatible and alternatives
* SEO-ready semantic HTML and JSON-LD structured data
* WhatsApp enquiry links

There is deliberately no cart, checkout, payment, shipping, stock, tax or coupon feature.

Cloudline automatically suppresses its JSON-LD when Yoast SEO, Rank Math or All in One SEO is active, preventing duplicate structured data. This can be changed under **Products > Catalogue settings > General**.

== Installation ==

1. Upload the `cloudline-product-catalogue` folder to `/wp-content/plugins/`.
2. Activate **Cloudline Product Catalogue** in WordPress.
3. Go to **Products > Catalogue settings** and add your WhatsApp number.
4. Add categories, brands and products from the Products menu.

Product archives and single pages use the `/products/` URL namespace. If you change rewrite settings or migrate from an older release, visit **Settings > Permalinks** and click **Save Changes** once to refresh WordPress rewrite rules.

== Shortcode reference ==

`[cpc_products]`

`[cpc_products category="medical-tools" per_page="8" columns="4" search="yes" filters="yes" featured="yes" orderby="title" order="ASC"]`

Attributes:

* `category`: category slug to show (optional)
* `per_page`: number of products, default 12
* `limit`: alias for `per_page`
* `columns`: 1 to 4, default 3
* `search`: `yes` or `no`, product search field (default `no`)
* `filters`: `yes` or `no`, category and brand filters (default `no`)
* `featured`: `yes` or `no`, show only products marked Featured (default `no`)
* `orderby`: `date`, `title`, `modified`, `menu_order` or `rand` (default `date`)
* `order`: `ASC` or `DESC` (default `DESC`)

The product search searches title, excerpt, description, product category, brand and all configured dynamic specification fields. Create a `SKU` or `Model Number` dynamic field if it should be searchable.

Quote Request is always enabled because it is the primary catalogue workflow. Its shortcode is:

* `[cpc_quote]` — always available
* `[cpc_compare]` — available when an external comparison add-on is installed

### Quote workflow

Visitors add products to the quote drawer, complete the request form, and receive a confirmation. Requests are stored as private `cpc_quote_request` posts under **Products > Quote requests** and emailed to the WordPress administrator. The drawer also offers a WhatsApp message containing the selected product names and links when a default WhatsApp number is configured.

Quote submissions include a honeypot and timing check plus a per-IP throttle of three accepted submissions per ten minutes. Integrations can replace or extend email delivery through `cpc_quote_email`, `cpc_before_send_quote`, and `cpc_after_send_quote`.

== Dynamic product fields ==

Go to **Products > Catalogue settings > Product fields** to create reusable specifications such as Material, Length, Width, Weight, Manufacturer, Warranty, Model Number, SKU and HSN Code. Fields can be text, long text, number or a select list. Each completed field displays in a semantic specifications table and is available to product comparison and catalogue search. Developers can change the definitions with `cpc_product_fields`.

== Core feature toggles ==

The **Products > Catalogue settings > Modules** screen provides independent toggles for gallery, videos, specifications, badges, relationships, search, filters, WhatsApp, SEO schema, breadcrumbs, brands, variants, packaging and downloads. Disabling a feature hides its UI and frontend output without deleting stored product data. Quote Request remains always enabled as the core enquiry workflow.

Variants and packaging are entered one value per line on the product editor. They are shown on cards and product pages, included in quote/WhatsApp context, searchable, and can be imported/exported through CSV. Badges are comma-separated display labels such as New, Best Seller or Recommended.

== Optional extensions ==

The core package contains the always-on Quote Request workflow and its registry/hooks. Documents, Enquiry Manager and Product Comparison are intentionally distributed as separate extensions so the catalogue remains lightweight. External extensions can register themselves with the `cpc_module_definitions` filter.

== Template override guide ==

Copy a template into the active theme before customising it:

`your-theme/cloudline-product-catalogue/single-product.php`

`your-theme/cloudline-product-catalogue/archive-product.php`

`your-theme/cloudline-product-catalogue/taxonomy-product-category.php`

`your-theme/cloudline-product-catalogue/product-card.php`

The copied template is used in preference to the plugin template. Do not edit plugin files.

== CSV import / export guide ==

Use **Products > Import / Export**. Export provides a spreadsheet-ready CSV. The importer always creates drafts for review. It does not download images from the web; upload image files through the Media Library first.

Accepted columns:

`title,content,excerpt,categories,brands,featured,badges,variants,packaging,availability,whatsapp_number,whatsapp_message,spec:field-key`

Use `|` to separate multiple category, brand, badge, variant or packaging values. A minimal example is:

`title,categories,brands,spec:material`

`Surgical Scissors,Surgical Instruments|Scissors,Cloudline,Stainless steel`

The configured dynamic-field key must match the text after `spec:`. Enquiry CSV export belongs to the optional Enquiry Manager extension.

WordPress's native Bulk Edit screen supports assigning product categories and brands to multiple selected products. The product list also includes a **Duplicate** row action.

== Hooks & filters ==

Actions:

* `cpc_before_product` — before a single product
* `cpc_after_product` — after a single product
* `cpc_before_archive` — before an archive listing
* `cpc_after_archive` — after an archive listing
* `cpc_before_summary` — before product summary content
* `cpc_after_summary` — after product summary content
* `cpc_before_gallery` — before a product gallery
* `cpc_after_gallery` — after a product gallery
* `cpc_before_specifications` — before the specification table
* `cpc_after_specifications` — after the specification table
* `cpc_before_quote_button` — before quote/enquiry actions
* `cpc_after_quote_button` — after quote/enquiry actions
* `cpc_product_actions` — inside the shared product-card or single-product actions container
* `cpc_before_whatsapp_button` — before a WhatsApp button
* `cpc_after_whatsapp_button` — after a WhatsApp button
* `cpc_before_product_card` — before a catalogue card
* `cpc_after_product_card` — after a catalogue card
* `cpc_product_modules_loaded` — after enabled modules initialise
* `cpc_product_meta_boxes` — register a product-editing metabox
* `cpc_product_saved` — after core product data is saved
* `cpc_enquiry_submitted` — after an enquiry is stored
* `cpc_quote_submitted` — after a quote request is stored
* `cpc_before_send_quote` — immediately before the quote email is sent
* `cpc_after_send_quote` — after the quote email attempt completes

Filters:

* `cpc_product_fields` — dynamic specification definitions
* `cpc_product_card_markup` — complete card markup
* `cpc_whatsapp_url` — WhatsApp link
* `cpc_product_schema` — Product JSON-LD array
* `cpc_should_output_schema` — enable or disable Cloudline JSON-LD output
* `cpc_template_path` — resolved template path
* `cpc_module_definitions` — optional module registry
* `cpc_feature_definitions` — extend the core feature toggle registry
* `cpc_duplicate_product_meta` — control metadata copied by Duplicate
* `cpc_quote_email` — customize the quote email payload

== Module development ==

Modules are registered through `cpc_module_definitions`. A definition needs a stable ID, label, description and class name. It may provide a PHP filename (loaded from the core `includes/modules/` directory by default), an absolute `path` directory, or a callable `loader` for a separately installed extension. The class should expose `public static function instance()` and attach its own hooks only when Cloudline loads it. Store module data in post meta or a dedicated post type; do not modify catalogue core files.

Example:

`add_filter( 'cpc_module_definitions', function( $modules ) { $modules['sample'] = array( 'name' => 'Sample', 'description' => 'Example module', 'file' => 'class-cpc-module-sample.php', 'path' => WP_CONTENT_DIR . '/my-cpc-extension/includes/', 'class' => 'CPC_Module_Sample', 'shortcode' => '' ); return $modules; } );`

Modules must not add cart, checkout, payment, shipping, tax, inventory or coupon features. Cloudline is intentionally a B2B catalogue and enquiry framework, not a WooCommerce replacement.
