Skip to content

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, ref are the essentials; logo/hero/screenshots[]/video render in the card + detail modal (repo- relative paths resolve against ref).
  • taxonomy — your types (filter pills) and categories. These are unioned across sources, so a type you introduce just appears in the filters. Nothing to register.
  • pricing.modelfree · 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 priority wins a collision and enriches the other's fields.
  • Sponsored / Featured — a live-api listing 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 a licensed (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.