Modules

The manifest

[module]
id = "blog"                 # folder name; lowercase, digits, dashes
name = "Blog"
version = "1.0.0"
description = "Posts, categories and a feed widget."
gansey = ">=0.1"           # core versions this works with
runtime = "script"
entry = "main.gansey"
source = "official"         # official | community | local

[permissions]
db = ["posts"]              # tables it may create and query
routes = ["/blog", "/blog/*"]
widgets = ["blog-feed"]
admin = ["Posts"]
hooks = ["head", "page.published"]
http = ["api.example.test"] # hosts it may call; ["*"] for any public address (see Public forms and webhooks)
email = false
jobs = false
media = false               # "read" the media library, or "manage" it (see Media)
cache = false               # read, clear and configure the page cache
pages = false               # read the site's published pages
files = false               # receive uploads and keep files (see Files)
sign = false                # sign stored files with the site's signing key
calls = []                  # hooks in other modules it may call and wait for
users = []                  # roles it may invite people into, grant and revoke, e.g. ["member"]
content = false             # "read" content types and entries, or "write" them (see Content)
read_users = false          # look up accounts: names, emails, roles
locales = false             # serve the site under language prefixes (see Language prefixes)

[requires]                  # other modules this one needs (see Modules that need modules)
forms = ">=1.0"

Permissions are enforced by core: a call outside them returns Err with a clear message, and a module that oversteps during init fails to load.