Running a site
Content packages
Keep a site's content as YAML in the repository — to seed a new server, move content between sites, or review it as a diff.
A content package is a directory of YAML describing pages, posts, terms, globals, menus, redirects and asset details.
Keep one in the repository and it is how a new server — or a demo copy of the site — gets its content. Tidewater keeps
its package beside its theme, in site/themes/tidewater/default_content/: Nibble never reads a package on its own, so
it can live anywhere except site/content/, which is for content written as files.
After reading this guide, you will know:
- What a package is for, and how it differs from content written as files.
- How to export one from a running site.
- The layout of a package, and what each file holds.
- How to import one safely, from a terminal or the control panel.
1. What it is for
A package is a seed, not a source. Importing one creates ordinary records, and afterwards the control panel edits them like any other; nothing syncs back, and changing a page in the control panel does not change the file.
| Content package | Content as files | |
|---|---|---|
| the files are | a starting point | the collection itself |
| after import | edited in the control panel | never edited in the control panel |
| brought in | once, by hand | every time the site starts |
Use a package to put content into a new database, to move content from one site to another, or to review a batch of content as a diff before it goes in.
2. Exporting
bin/rails nibble:content:export site/themes/tidewater/default_content
writes everything to site/themes/tidewater/default_content/. Narrow it with --collections=pages,posts,
--taxonomies=topics, --locales=en or --status=published. Commit what it writes.
Tip
Export after every batch of content changes worth keeping — a relaunched pricing page, a quarter’s posts — so the repository always holds a recent copy that a demo or a new server can start from.
3. The layout
site/themes/tidewater/default_content/
├── globals/site/en.yml
├── navigation/main/en.yml
├── collections/pages/en/home.yml
├── collections/pages/en/pricing.yml
├── collections/posts/en/late-invoices.yml
├── taxonomies/authors/en/priya-nair.yml
├── taxonomies/topics/en/cash-flow.yml
├── redirects.yml
└── assets.yml
A file’s name is the record’s slug, and its folder says which collection or taxonomy and which locale it belongs to.
A global is its fields:
# site/themes/tidewater/default_content/globals/site/en.yml
name: Tidewater
tagline: Invoicing that gets you paid
contact_email: hello@tidewater.example
A menu is a tree. A link is a url, or an entry named as <collection>/<slug>, so it survives the entry being
given a new ID in a new database:
# site/themes/tidewater/default_content/navigation/main/en.yml
tree:
- entry: pages/pricing
title: Pricing
- url: "/blog"
title: Blog
An entry is its fields, blocks included; redirects.yml and assets.yml are lists.
4. Importing
bin/rails nibble:content:validate site/themes/tidewater/default_content # check it, write nothing
bin/rails nibble:content:import site/themes/tidewater/default_content
On a server:
bin/kamal app exec 'bin/rails nibble:content:import site/themes/tidewater/default_content'
| Option | What it does |
|---|---|
--mode=create |
adds what is missing and leaves everything else alone — the default |
--mode=update |
also overwrites records that already exist with the package’s version |
--dry-run |
validates and reports, writes nothing |
--webhooks |
delivers webhooks for what was imported |
Every field must exist in the blueprint and hold a value it accepts. The whole package is validated before anything is written, so a typo stops the import rather than half-filling a database.
Caution
--mode=update replaces what editors have changed since the package was made. Use it on a database you are
happy to overwrite — a demo, a fresh copy — not on the live site.
Warning
assets.yml holds each asset’s details — alt text, focal point, folder — but not the file. An import in update
mode refreshes the details of assets that already exist and skips everything else, so move the files themselves
separately: upload them again, or copy the storage volume or bucket.
4.1 From the control panel
Utilities has the same thing for people without a terminal: export downloads the site’s content as a zip, and import takes one, shows what it would create or change, and only writes when you confirm. Both need their own permissions, and ask for your password again.
5. On a fresh install
bin/rails nibble:install offers Nibble’s own example pages and posts, so a new site is not an empty screen. That is
Nibble’s starter content, unrelated to your package; your package is never imported unless you ask.
Note
A theme never ships content. A theme is layouts, views, components, styles and schema, so it can serve many sites without carrying any of them.