diff --git a/.gitignore b/.gitignore index cf8b1ff..d2fe01d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ releases collerd.db !docker/collerd.json collerd.json +node_modules diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4cf810c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,40 @@ +{ + "name": "coller", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "bootstrap": "^5.3.8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..719e5df --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "bootstrap": "^5.3.8" + } +} diff --git a/src/cmd/collerd/README.md b/src/cmd/collerd/README.md index d99a273..0b51d6a 100644 --- a/src/cmd/collerd/README.md +++ b/src/cmd/collerd/README.md @@ -34,6 +34,7 @@ The file format is **JSON**: * **languages** ([]string): List of supported [languages](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages) * **language** (string): Default language (default "text") * **enable_upload_file_button** (bool): Display the upload file button in the UI (default true) +* **bootstrap_directory** (string): Serve [Bootstrap](https://getbootstrap.com/) assets from this local directory (ex: "./node_modules/bootstrap/dist"). See **Dependencies** for details. The configuration file is not required but the service might not be exposed to the public. @@ -76,4 +77,27 @@ If the note is encrypted, the encrypted value is returned (application/octet-str Errors return **500 Server Internal Error** with the **JSON** payload: * **message** (string): context of the error -* **error** (string): error message \ No newline at end of file +* **error** (string): error message + +## Dependencies + +The web interface depends on: + +- [Bootstrap](https://getbootstrap.com/) +- [Monaco Editor]https://github.com/microsoft/monaco-editor/) + +By default, those dependencies are fetched from **remote CDN** services by the client. + +If you would like to download them to serve them locally: + +``` +npm install +``` + +Then configure the local directories: + +```json +{ + "bootstrap_directory": "./node_modules/bootstrap/dist" +} +``` \ No newline at end of file diff --git a/src/server/config.go b/src/server/config.go index 8ba51ca..e1ef5e7 100644 --- a/src/server/config.go +++ b/src/server/config.go @@ -26,6 +26,7 @@ type Config struct { Languages []string `json:"languages"` Language string `json:"language"` EnableUploadFileButton bool `json:"enable_upload_file_button"` + BootstrapDirectory string `json:"bootstrap_directory"` } func NewConfig() *Config { diff --git a/src/server/server.go b/src/server/server.go index 703714d..ab61605 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -195,6 +195,7 @@ type PageData struct { URL string Note *Note EnableUploadFileButton bool + BootstrapDirectory string } type HomeHandler struct { @@ -429,10 +430,11 @@ func (s *Server) Start() error { "string": func(b []byte) string { return string(b) }, } p := PageData{ - Title: s.config.Title, - Expirations: s.config.Expirations, - Expiration: s.config.Expiration, - Languages: s.config.Languages, + Title: s.config.Title, + Expirations: s.config.Expirations, + Expiration: s.config.Expiration, + Languages: s.config.Languages, + BootstrapDirectory: s.config.BootstrapDirectory, } if s.config.ShowVersion { @@ -469,6 +471,10 @@ func (s *Server) Start() error { } r.Path("/{id:[a-zA-Z0-9]+}.html").Handler(webNoteHandler).Methods("GET") + if s.config.BootstrapDirectory != "" { + r.PathPrefix("/static/bootstrap/").Handler(http.StripPrefix("/static/bootstrap/", http.FileServer(http.Dir(s.config.BootstrapDirectory)))) + } + r.Path("/").Handler(&HomeHandler{Templates: templates, PageData: p}).Methods("GET") addr := fmt.Sprintf("%s:%d", s.config.ListenAddress, s.config.ListenPort) diff --git a/src/server/templates/head.html b/src/server/templates/head.html index bd8edba..e5f3544 100644 --- a/src/server/templates/head.html +++ b/src/server/templates/head.html @@ -4,6 +4,6 @@