1
0
Fork 0
forked from jriou/coller

feat: Option to serve Bootstrap from the filesystem

Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
Julien Riou 2025-09-16 09:36:10 +02:00
commit ff92e30232
Signed by: jriou
GPG key ID: 9A099EDA51316854
8 changed files with 94 additions and 6 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@ releases
collerd.db
!docker/collerd.json
collerd.json
node_modules

View file

@ -55,6 +55,9 @@ releases: build_linux_amd64 build_darwin_arm64 archive_linux_amd64 archive_darwi
releases_with_docker:
docker run -it -v $(shell pwd):/mnt -w /mnt -e "UID=$(shell id -u)" -e "GID=$(shell id -g)" ${DOCKER_IMAGE} ./docker/build.sh
dependencies:
npm install
test:
cd src \
&& go test internal/*.go \

40
package-lock.json generated Normal file
View file

@ -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"
}
}
}
}

5
package.json Normal file
View file

@ -0,0 +1,5 @@
{
"dependencies": {
"bootstrap": "^5.3.8"
}
}

View file

@ -36,6 +36,7 @@ The file format is **JSON**:
* **enable_upload_file_button** (bool): Display the upload file button in the UI (default true)
* **tls_cert_file** (string): Path to TLS certificate file to enable HTTPS
* **tls_key_file** (string): Path to TLS key file to enable HTTPS
* **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.
@ -78,4 +79,35 @@ 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
* **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
```
or via `make`:
```
make dependencies
```
Then configure the local directories:
```json
{
"bootstrap_directory": "./node_modules/bootstrap/dist"
}
```
Downloading Monaco Editor is not supported yet.

View file

@ -28,6 +28,7 @@ type Config struct {
EnableUploadFileButton bool `json:"enable_upload_file_button"`
TLSCertFile string `json:"tls_cert_file"`
TLSKeyFile string `json:"tls_key_file"`
BootstrapDirectory string `json:"bootstrap_directory"`
}
func NewConfig() *Config {

View file

@ -196,6 +196,7 @@ type PageData struct {
URL string
Note *Note
EnableUploadFileButton bool
BootstrapDirectory string
}
type HomeHandler struct {
@ -430,10 +431,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 {
@ -470,6 +472,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)

View file

@ -4,6 +4,6 @@
<title>{{.Title}}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="{{if ne .BootstrapDirectory ``}}/static/bootstrap/css/bootstrap.min.css{{else}}https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css{{end}}" rel="stylesheet">
</head>
{{end}}