Marketplaces & sources
The Add Module screen isn't hard-wired to one catalog. It's an aggregator: it reads an ordered list of sources and merges them into one browsable directory. Anyone can add a source — the WebTigers directory, the WebTigers marketplace, or your own. This page shows how.
The one idea: a source is any URL that returns a Tiger catalog index. Serve that JSON and your marketplace shows up in every Tiger install that adds you — deduped, filtered, searchable, and degradation-safe. You don't touch the Add screen, and you never edit core.
Two kinds of source
| Kind | Is | Hosting | Trust |
|---|---|---|---|
Directory (git-index) |
a static, public index.json |
a git repo / any static host — no server | public, reviewable, always up |
Marketplace (live-api) |
an endpoint serving the same shape, enriched (ratings, downloads, a paid catalog) | your server | operator-run — informed trust |
Both fetch a URL and return the same payload. kind only records provenance (and is the seam where a
live-api source later gains auth / caching). Start with a directory; graduate to a live API when you want
dynamic data.
The index shape
A source returns one JSON document:
{
"taxonomy": {
"types": [ { "id": "app", "label": "Apps" }, { "id": "theme", "label": "Themes" } ],
"categories": [ { "id": "commerce", "label": "Commerce", "types": ["app"] } ]
},
"modules": [
{
"slug": "acme-invoices",
"module": "Acme Invoices",
"vendor": "Acme",
"type": "app",
"category": "commerce",
"description": "Send and track invoices.",
"repository": "https://github.com/acme/tiger-invoices",
"ref": "v1.2.0",
"logo": "media/logo.png",
"pricing": { "model": "free" }
}
]
}
modules[]— the listings.slug,module(title),vendor,type,description,repository,refare the essentials;logo/hero/screenshots[]/videorender in the card + detail modal (repo- relative paths resolve againstref).taxonomy— yourtypes(filter pills) andcategories. These are unioned across sources, so a type you introduce just appears in the filters. Nothing to register.pricing.model—free·freemium·paid(sold off-platform) ·licensed(sold through the Module Manager against your own license authority — see Marketplace & licensing).
That's the whole contract. Everything below is automatic:
- Merge + dedupe by slug — lower
prioritywins a collision and enriches the other's fields. - Sponsored / Featured — a
live-apilisting may set"sponsored": true(+sponsored_rank); the Featured sort floats those first. Every other sort is neutral. - Offline-safe — a source that's down is skipped (its last-good cache is served), so one outage never breaks the screen.
Adding a source — two paths
1. In the UI (any admin)
Add Module → Marketplaces → Connect a marketplace. Paste a name and the index URL, pick Directory or Marketplace, and connect. It's stored in the install's config tier (the admin owns it, survives updates), and you can enable/disable, re-order by priority, or remove it right there. No code.
2. From a module (a developer)
Ship a module that bundles its marketplace, so activating the module adds the source and deactivating it
removes the source — nothing to clean up. Register it from your module's Bootstrap:
class Acme_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAcmeMarketplace()
{
Tiger_Module_Registry::register('acme', [
'label' => 'Acme Market',
'kind' => 'live-api', // or 'git-index'
'url' => 'https://acme.example/tiger/index.json',
'priority' => 20, // lower = checked first
], 'acme-market'); // your module slug (shown in the manage UI)
}
}
Tiger_Module_Registry::register() is in-memory and re-declared each request (the same pattern as
Tiger_Audience::register() / Tiger_Search::register()), so the source lives exactly as long as your
module is active. An admin can still disable or re-order it from the Marketplaces tab — a config override
always wins over what a module registered.
Priority — where you rank
Sources sort by priority ascending; lower is earlier and wins a slug collision. The shipped sources
are the WebTigers marketplace at 0 and the WebTigers directory at 10. Pick a number that reflects how
you want to compose:
- Below 10 — your marketplace enriches/overrides directory listings for shared slugs.
- Above 10 — you fill in modules the directory doesn't have, and defer to it on collisions.
Trust & safety
Curation is open — core doesn't gatekeep who lists what — but integrity isn't optional:
- An admin adds only sources they trust; the UI says plainly that a source lists modules whose code runs on their server once installed.
- Every install is reviewed before it runs (the detail modal shows the repo +
TIGER.md), and alicensed(paid) module must arrive signed — verified against the vendor's pinned key before extraction. See Marketplace & licensing for the full protocol (running a license authority, signed artifacts, and the buyer-side client that's already in core).
In short
Serve one JSON file, and you're a marketplace. Register it in ten lines, and your module carries its own storefront. That's the whole point — the platform's distribution is open by design, so a niche vendor, an agency, or a whole community can run their own catalog without asking anyone's permission.