Search by

silvershop-suite / product-feed-channable

RVXD

Channable (complete / raw) feed connector for silvershop-suite/product-feed (CMS 6): a flat, un-namespaced 'expose every field' XML serializer + field map that turns the shared CatalogProductData into a rich source feed Channable pulls from a stable URL and remaps itself. Registers itself into the p

Package info

github.com/silvershop-suite/silvershop-product-feed-channable

Type:silverstripe-vendormodule

pkg:composer/silvershop-suite/product-feed-channable

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-10-24 12:37 UTC

This package is not auto-updated.

Last update: 2026-10-24 13:29:40 UTC


README

CI

The Channable channel connector for silvershop-suite/product-feed on Silverstripe CMS 6. It plugs a complete, flat, un-namespaced product feed into the feed core's registry seam: a vendor-neutral RawXmlFormat serializer plus a field map that emits every CatalogProductData field. No core change — the connector registers itself.

product-feed core ──(registry)──▶ ChannableChannelFeed.mapItem() ──▶ RawXmlFormat ──▶ public/feeds/channable.xml
                                   (every VO field, flat)             (flat, un-namespaced XML)   served at /feed/channable

Why it is so thin

Channable is a feed aggregator: you import one rich source feed once, then Channable's own rule engine maps and optimises it per output channel (Google, bol.com, Amazon, Marktplaats, Facebook, …). So this connector deliberately carries no Channable-specific field logic — its whole value is completeness and flatness. Where silvershop-suite/product-feed-google maps the VO to tightly-specified, g:-namespaced, taxonomy-resolved attributes with nested g:shipping, this dumps all fields, flat, neutrally named, and lets Channable slice them.

Because RawXmlFormat is vendor-neutral, any other pull-based feed tool (Producthero, Tweakwise, …) is a thin re-registration of the same format under its own channel key — not a fork.

Requirements

  • PHP 8.3+, silverstripe/framework ^6, silvershop/core ^6.2
  • silvershop-suite/product-feed (the feed core; pulls in silvershop-suite/catalog-data transitively)

Release ordering. silvershop-suite/product-feed and silvershop-suite/catalog-data gate this connector — a known core → connector ordering dependency. For development and the clean-room, install product-feed + catalog-data (and the connector itself) as path repositories.

Installation

composer require silvershop-suite/product-feed-channable

Then dev/build?flush=all. This registers + enables the channable channel in the feed core (installing the connector means you want the complete feed).

Generating & serving

The feed core owns generation, scheduling and serving (see its README). With this connector installed:

  • generate: sake tasks:ProductFeed-Generate --channel=channable (or let the recurring GenerateProductFeedJob do it), written to public/feeds/channable.xml;
  • serve: https://your-shop/feed/channable (the core's serving route).

Because a complete feed exposes the whole catalogue, set the core's ProductFeedController.access_token and hand Channable the tokened URL (…/feed/channable?token=<secret>) — an existing core feature, no connector code.

Configure Channable to pull the feed

  1. In Channable: Projects → Imports → add an import → from a URL.
  2. Paste https://your-shop/feed/channable (add ?token=<secret> if a core access token is set).
  3. Format XML; set the refresh to match GenerateProductFeedJob.regenerate_interval_mins (default nightly).
  4. Map the fields below to each output channel with Channable's rules.

Channable only supports flat XML/JSON and ignores values held in XML attributes. This feed is flat and attribute-free by construction (that is why it is not the Google RSS format).

The flat field map

Every element is lower_snake_case, un-namespaced, and scalar (a list becomes repeated sibling elements). Empty values are omitted.

Element Source (CatalogProductData) Notes
id feedId() = conversion-tracking content_ids — Channable's unique key
item_group_id itemGroupId() parent feed id for variants; omitted for simple products
title / description / link title() / description() / link()
image_link / additional_image_link imageLink() / additionalImageLinks() additional_image_link repeats
availability availability() in_stock / out_of_stock / preorder / backorder
price / sale_price formattedPrice() / formattedSalePrice() "89.95 EUR" (see price_as)
currency currency() discrete ISO-4217 code
brand / gtin / mpn brand() / gtin() / mpn() gtin/mpn via silvershop-suite/product-identity
identifier_exists identifierExists() no only when no gtin + mpn + brand, else omitted
condition condition() new / refurbished / used
product_type productType() the shop's full category path (no root trim — Channable remaps)
secondary_product_type secondaryCategories() repeated; the product's additional category placements
quantity quantity() finite stock level (silvershop/stock); omitted when unlimited/untracked
weight / height / width / depth weight() / height() / width() / depth() core shipping fields
last_modified lastModified() ISO-8601; for a channel's delta logic
(variant attributes) attributes() flattened to one element per attribute (<color>, <size>, slugified labels)

All text is XML-escaped (XSS-safe) and the document is well-formed, flat XML.

Config

SilverShop\ProductFeed\Channable\ChannableChannelFeed:
  price_as: 'combined'      # "89.95 EUR" (default); 'split' emits a bare numeric price + the currency element
  include_attributes: true  # flatten variant attributes into their own elements

Licence

BSD-3-Clause.

Credits

Built and maintained by Remy Vaartjes (remy@xd.nl) — part of the SilverShop-Suite.