Skip to content

Commit d93cf68

Browse files
Site changes [skip-ci]
1 parent 7224d3f commit d93cf68

File tree

2 files changed

+58622
-58035
lines changed

2 files changed

+58622
-58035
lines changed

manuals/editor-scripts.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
layout: manual
33
language: en
44
github: https://github.com/defold/doc
5-
toc: ["Editor scripts","Editor script runtime","Anatomy of .editor_script","Use commands to change the in-memory editor state","Lifecycle hooks","Editor scripts in libraries","Preferences","Execution modes","Actions","Undoable actions","Mixing actions and side effects"]
5+
toc: ["Editor scripts","Editor script runtime","Anatomy of .editor_script","Use commands to change the in-memory editor state","Lifecycle hooks","HTTP server","Non-undoable actions"]
66
title: Editor scripts
77
brief: This manual explains how to extend editor using Lua
88
---
@@ -249,6 +249,68 @@ Language server definition table may specify:
249249
- `command` (required) - an array of command and its arguments
250250
- `watched_files` - an array of tables with `pattern` keys (a glob) that will trigger the server's [watched files changed](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWatchedFiles) notification.
251251

252+
## HTTP server
253+
254+
Every running instance of the editor has an HTTP server running. The server can be extended using editor scripts. To extend the editor HTTP server, you need to add `get_server_routes` editor script function — it should return the additional routes:
255+
```lua
256+
print("My route: " .. http.server.url .. "/my-extension")
257+
258+
function M.get_server_routes()
259+
return {
260+
http.server.route("/my-extension", "GET", function(request)
261+
return http.server.response(200, "Hello world!")
262+
end)
263+
}
264+
end
265+
```
266+
After reloading the editor scripts, you'll see the following output in the console: `My route: http://0.0.0.0:12345/my-extension`. If you open this link in the browser, you'll see your `"Hello world!"` message.
267+
268+
The input `request` argument is a simple Lua table with information about the request. It contains keys such as `path` (URL path segment that starts with `/`), request `method` (e.g. `"GET"`), `headers` (a table with lower-case header names), and optionally `query` (the query string) and `body` (if the route defines how to interpret the body). For example, if you want to make a route that accepts JSON body, you define it with a `"json"` converter parameter:
269+
```lua
270+
http.server.route("/my-extension/echo-request", "POST", "json", function(request)
271+
return http.server.json_response(request)
272+
end)
273+
```
274+
You can test this endpoint in the command line using `curl` and `jq`:
275+
```sh
276+
curl 'http://0.0.0.0:12345/my-extension/echo-request?q=1' -X POST --data '{"input": "json"}' | jq
277+
{
278+
"path": "/my-extension/echo-request",
279+
"method": "POST",
280+
"query": "q=1",
281+
"headers": {
282+
"host": "0.0.0.0:12345",
283+
"content-type": "application/x-www-form-urlencoded",
284+
"accept": "*/*",
285+
"user-agent": "curl/8.7.1",
286+
"content-length": "17"
287+
},
288+
"body": {
289+
"input": "json"
290+
}
291+
}
292+
```
293+
The route path supports patterns that can be extracted from the request path and provided to the handler function as a part of the request, e.g.:
294+
```lua
295+
http.server.route("/my-extension/setting/{category}.{key}", function(request)
296+
return http.server.response(200, tostring(editor.get("/game.project", request.category .. "." .. request.key)))
297+
end)
298+
```
299+
Now, if you open e.g. `http://0.0.0.0:12345/my-extension/setting/project.title`, you'll see the title of your game taken from the `/game.project` file.
300+
301+
In addition to a single segment paths pattern, you can also match the rest of the URL path using `{*name}` syntax. For example, here is a simple file server endpoint that serves files from the project root:
302+
```lua
303+
http.server.route("/my-extension/files/{*file}", function(request)
304+
local attrs = editor.external_file_attributes(request.file)
305+
if attrs.is_file then
306+
return http.server.external_file_response(request.file)
307+
else
308+
return 404
309+
end
310+
end)
311+
```
312+
Now, opening e.g. `http://0.0.0.0:12345/my-extension/files/main/main.collection` in the browser will display the contents of the `main/main.collection` file.
313+
252314
## Editor scripts in libraries
253315

254316
You can publish libraries for other people to use that contain commands, and they will be automatically picked up by the editor. Hooks, on the other hand, can't be picked up automatically, since they have to be defined in a file that is in a root folder of a project, but libraries expose only subfolders. This is intended to give more control over build process: you still can create lifecycle hooks as simple functions in `.lua` files, so users of your library can require and use them in their `/hooks.editor_script`.

0 commit comments

Comments
 (0)