Add an admin to an app
You will add a studio at /admin to an app that already uses gisila_orm, register two models,
and sign in to browse and edit them.
Prerequisites
Section titled “Prerequisites”- A Postgres database and gisila_orm models generated from a
.gisila.yamlschema, with migrations applied. See the ORM section. - A
database.yaml(or another way to build aDatabaseConfig).
1. Add the dependency
Section titled “1. Add the dependency”dependencies: gisila_orm: ^0.2.0 gisila_studio: ^0.3.0 shelf: ^1.4.1 shelf_router: ^1.1.4dart pub get2. Create the studio and register models
Section titled “2. Create the studio and register models”import 'package:gisila_orm/gisila.dart';import 'package:gisila_studio/gisila_studio.dart';import 'package:shelf/shelf.dart';
import 'models/blog.gisila.g.dart';
Handler buildAdmin(Database db) { final studio = GisilaStudio(db: db, title: 'Blog Admin');
studio.register<User>( UserTable.metadata, listDisplay: ['id', 'firstName', 'lastName', 'email', 'dateJoined'], searchFields: ['firstName', 'lastName', 'email'], readonlyFields: ['id', 'dateJoined'], onSave: {'password': (v) => hashPassword(v as String)}, // your app's hasher ordering: ['-dateJoined'], group: 'Users & Auth', );
studio.register<Author>( AuthorTable.metadata, listDisplay: ['id', 'firstName', 'lastName', 'email'], searchFields: ['firstName', 'lastName', 'email'], readonlyFields: ['id'], );
return studio.handler(prefix: '/admin');}handler(prefix:) must get the same path you mount it at.
3. Mount it
Section titled “3. Mount it”Plain Shelf:
import 'package:gisila_orm/gisila.dart';import 'package:shelf/shelf.dart';import 'package:shelf/shelf_io.dart' as io;import 'package:shelf_router/shelf_router.dart';import 'package:blog/admin.dart';
Future<void> main() async { final db = await Database.connect(await DatabaseConfig.fromFile('database.yaml'));
final router = Router() ..get('/', (Request _) => Response.found('/admin/')) ..mount('/admin', buildAdmin(db));
final handler = const Pipeline().addMiddleware(logRequests()).addHandler(router.call); await io.serve(handler, '0.0.0.0', 8080);}Inside a gisila app: mount it from a controller attacher, next to your controllers:
app.registerController(attacher: (app, router, {String prefix = ''}) { router.mount('/admin', buildAdmin(db));});gisila’s global middleware (logging, CORS, rate limits) then applies to studio requests too. See the framework section.
4. Provide credentials
Section titled “4. Provide credentials”The studio will not serve without a login. Set a username and a password of at least 12 characters:
export STUDIO_USERNAME=adminexport STUDIO_PASSWORD='correct-horse-battery'# optional, for JWT sessions that work across isolates and restarts:export STUDIO_SECRET="$(openssl rand -base64 48)"dart run bin/server.dartFor a throwaway local database you can instead pass allowUnauthenticated: true to
GisilaStudio; never do that on a reachable server.
Verify it works
Section titled “Verify it works”curl -si localhost:8080/admin/ | head -3# HTTP/1.1 302 FoundIf you get 503 instead, read the server’s stderr: it says why the studio is disabled (missing or
weak credentials).
Open http://localhost:8080/admin/, sign in, and you should see the dashboard with Users and
Authors and their row counts. Click Users, use the search box, open a row, edit a field
and save.
Next steps
Section titled “Next steps”- Customize lists and forms
- Secure the studio before deploying.
- GisilaStudio reference