silvershop-suite / product-feed-channable
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
Requires
- php: ^8.3
- silvershop-suite/catalog-data: ^1.1
- silvershop-suite/product-feed: ^1
- silvershop/core: ^6.2
- silverstripe/framework: ^6
Requires (Dev)
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-24 13:29:40 UTC
README
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 insilvershop-suite/catalog-datatransitively)
Release ordering.
silvershop-suite/product-feedandsilvershop-suite/catalog-datagate 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 recurringGenerateProductFeedJobdo it), written topublic/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
- In Channable: Projects → Imports → add an import → from a URL.
- Paste
https://your-shop/feed/channable(add?token=<secret>if a core access token is set). - Format XML; set the refresh to match
GenerateProductFeedJob.regenerate_interval_mins(default nightly). - 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.