Orkestia
Blog
Media

Templates as code

Keep video templates in a repository, review them in pull requests and load them into your organization from CI with plan and apply

TL;DR

orkestia video templates validate | plan | apply loads templates from templates/**/*.template.{ts,js} (or plain JSON documents) and saves them into your organization. Each template has a stable key (<namespace>/<id>), so apply writes the next version of the same template and never a duplicate. Nothing is ever deleted.

Commands

orkestia video templates validate                     # build every template offline; every finding at once
orkestia video templates plan  --namespace=acme       # create / update / unchanged / orphan, by content hash
orkestia video templates apply --namespace=acme --yes # save what changed (video.template.save with the key)
  • plan compares the canonical JSON's sha256 with the saved version. It needs a member token (read only).
  • apply without --yes prints the plan and stops. Identical content is a no-op on the server.
  • A template in the organization but not in code is an orphan: reported, never removed.
  • --dir=<path> changes the folder (default templates).

A template file

A file default-exports a builder or a plain orkestia.template.v1 document. A generic (scenes) template as JSON:

{
  "schema": "orkestia.template.v1",
  "kind": "scenes",
  "blocks_version": "scenes@1",
  "name": "Product update",
  "locale": "en-US",
  "formats": ["4x5", "9x16", "16x9"],
  "themes": ["dark", "light"],
  "disclosure": "none",
  "slots": [
    { "id": "headline", "type": "rich", "label": "Headline", "max_length": 80, "required": true },
    { "id": "photo", "type": "image", "label": "Photo" },
    { "id": "points", "type": "list", "label": "What changed", "max_items": 5 }
  ],
  "composition": {
    "scenes": [
      { "type": "title", "frames": 90, "kicker": "New", "title": "{{headline}}" },
      { "type": "image", "frames": 120, "src": "{{photo}}", "caption": "In the app today" },
      { "type": "list", "frames": 150, "title": "What changed", "items": "{{points}}" },
      { "type": "end", "frames": 90, "title": "Try it [[today.]]", "cta": "example.com" }
    ]
  }
}

frames are at 30 per second. The typed builder (template("id", {...}).slot(...)) covers chat videos today; write generic scene templates as JSON.

Working with the editor

People can still edit keyed templates in the studio. Their save is a new version; the next apply saves the code's version on top when it differs. Keep templates you load from code edited in code.