The engine, the module system, and the ideas everything else follows.

How is Convoro organised? engine/ is the framework, modules/ holds System and the applications, themes/ holds templates and assets, and public/ is the only directory a web server needs to see. There is no vendor directory and no build output. Developers How do I create a new module? A directory under modules/ with a manifest.json and a class named after it extending Module, with register() and boot(). Routes, migrations, services and templates are found by convention from there. Developers What is the difference between register and boot in a module? register() binds services and registers into registries; boot() does work that may depend on other modules. Every module registers before any module boots, which is why widget areas must be registered in register(). Developers How do I add a database table or column? Add a dated file to your module's Migrations/ returning an anonymous class extending Migration with up() and down(). Run php tools/convoro migrate. Make it re-runnable — check before you alter. Developers How do I add a page to Convoro? Put it in your module's Routes/front.php or Routes/admin.php. Register literal paths before patterns, or a slug will shadow them. Developers What is the .cvr template syntax? Templates are .cvr files compiled to PHP. {{ }} escapes, {! !} does not, and the directives are @layout, @section, @yield, @if, @each, @empty, @notempty, @include, @php, @hook, @csrf and @asset. Developers How do I use the database or another service in my code? Everything is in the container. $this->app->make('db') for the query builder, and the same for anything a module bound in register(). Bind your own with $this->app->singleton(). Developers How do I make my module's content respect permissions? Add a <thing>_groups table, check the viewer's group ids against it in your service, and add the table to Groups::RESTRICTION_TABLES. Enforce it in the service, never in a template. Developers How should my module accept a file upload? Sniff the type from the bytes, never the filename or Content-Type; store outside the document root and serve through a controller; and add the path to the nginx list or it will 404 only in production. Developers How do I run and write tests? php tests/run.php, optionally with a filter. A test file returns an array of name => callable and passes if it does not throw. Clean up what you create, in a finally. Developers