Exemplos
Programas pequenos e completos. Salve em um arquivo e rode com djo arquivo.djo, ou coloque numa pasta e use djo serve.
Structs
Campos tipados, valores padrão e métodos. O campo nocall fica fora do construtor.
struct Post{
id[Int] nocall
titulo[String]
publicado[Bool] = false
f link
return "/post?id=" + (str:self.id)
}
var p = Post:"Olá"
p.id = 7
print p.link: // /post?id=7
Uma API JSON
Páginas em modo código: o que print escreve é a resposta, ou use Http.json: para responder JSON com o status que quiser.
// api.djo: uma página que responde JSON
if
cond[Http.method: == "POST"]
var d = Http.json:
Http.json:{"recebido": d["n"] + 1}:201
else
Http.json:{"erro": "use POST"}:405
Banco de dados
SQLite embutido. Os valores vão sempre numa lista, ligados aos ?, o que evita SQL injection.
Db.open:"site.db"
Db.exec:"CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY, titulo TEXT)"
Db.exec:"INSERT INTO posts (titulo) VALUES (?)":[Http.form:"titulo"]
var posts = Db.query:"SELECT * FROM posts ORDER BY id DESC LIMIT 10"
for{
each[p in posts]
print p["titulo"]
}
Sensor na placa
Lê uma linha da porta serial a cada segundo e envia para um servidor. Compile o perfil tiny ou nano para a sua placa.
// sensor.djo: lê a porta serial e envia a leitura para o servidor
var porta = Serial.open:"/dev/ttyUSB0":9600
while
cond[true]
var linha = Serial.readline:porta
if
cond[linha != nil]
map leitura = {"sensor": "sala", "temp": float:linha, "hora": Time.now:}
var r = Http.post:"http://192.168.0.10:8080/leituras":leitura
if
cond[not r["ok"]]
print "não enviou: " + (r["error"] ?? str:r["status"])
Time.sleep:1000
Tela e agente na mesma URL
No rotas.djo, a rota aponta para duas páginas. Quem pede application/json recebe a face de agente; o navegador recebe o HTML. Pedir um formato que a rota não tem dá 406.
// rotas.djo: a mesma URL tem uma face para pessoas e outra para agentes
Route.get:"/docs/{secao}":{"html": "paginas/doc.djo.html", "agent": "agentes/doc.djo"}
Uma ação para agentes
Com action, uma função com parâmetros tipados vira um endpoint POST em JSON. A entrada é validada contra os tipos antes de a função rodar (erro 422 com o detalhe de cada campo), e o servidor publica o manifesto em /.well-known/ai-manifest.json, com JSON Schema, para quem usa function calling ou MCP.
// core/posts.djo: a mesma função serve a tela e o agente
action criar_post
"Cria um post novo"
params[titulo[String], nota[Float]]
Http.status:201
return {"titulo": titulo, "nota": nota}
// rotas.djo
Route.action:"/posts":"criar_post"
Para ver o seu site como um agente: djo agent localhost:8080. Agentes
Este site
Você está lendo um site feito em djo. Estas páginas são templates .djo.html, o realce de código e o renderizador de Markdown da documentação são funções djo em core/, e as rotas são estas:
// Este site é feito em djo. Só existe o que está declarado aqui.
Route.get:"/":"paginas/inicio.djo.html"
Route.get:"/docs":{"html": "paginas/docs.djo.html", "agent": "agentes/docs.djo", "about": "Índice da documentação da djo", "cache": 60}
Route.get:"/docs/{secao}":{"html": "paginas/doc.djo.html", "agent": "agentes/doc.djo", "about": "Uma seção da documentação, em Markdown", "cache": 60}
Route.get:"/exemplos":"paginas/exemplos.djo.html"
Route.get:"/instalar":"paginas/instalar.djo.html"
Route.static:"/assets":"publico"
Teste a face de agente: /docs com Accept: application/json, ou leia o manifesto deste site.