Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Fœdus reads its configuration from environment variables:
| `SPOTIFY_CLIENT_ID` | no | — | Enables the collaborative soundtrack |
| `SPOTIFY_CLIENT_SECRET` | no | — | Same as above |
| `SPOTIFY_REFRESH_TOKEN` | no | — | Same as above |
| `CARTO_API_KEY` | no | — | Publishable CARTO basemaps API key, appended to map tile requests; without it tiles load keyless |

\* The app accepts either the unsuffixed `ADMIN_USER` / `ADMIN_PASSWORD` pair or any number of suffixed `ADMIN_USER1..9` / `ADMIN_PASSWORD1..9` pairs — at least one valid pair must be set, otherwise the process panics at startup rather than expose the dashboard with default credentials.

Expand Down
40 changes: 21 additions & 19 deletions static/parking.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
const LEAFLET_JS_URL = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js";
let leafletAssetsPromise = null;

function cartoTileURL(style) {
const key = document
.querySelector("meta[name='carto-api-key']")
?.getAttribute("content");
const url = `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;
return key ? `${url}?key=${encodeURIComponent(key)}` : url;
}

let map = null;
let entries = [];

Expand Down Expand Up @@ -66,25 +74,19 @@
attributionControl: true,
});

L.tileLayer(
"https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
subdomains: "abcd",
maxZoom: 19,
},
).addTo(map);

L.tileLayer(
"https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png",
{
attribution: "",
subdomains: "abcd",
maxZoom: 19,
pane: "overlayPane",
},
).addTo(map);
L.tileLayer(cartoTileURL("light_nolabels"), {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
subdomains: "abcd",
maxZoom: 19,
}).addTo(map);

L.tileLayer(cartoTileURL("light_only_labels"), {
attribution: "",
subdomains: "abcd",
maxZoom: 19,
pane: "overlayPane",
}).addTo(map);

entries = buildEntries();
map.on("move zoom resize", render);
Expand Down
40 changes: 21 additions & 19 deletions static/places.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
const LEAFLET_JS_URL = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js";
let leafletAssetsPromise = null;

function cartoTileURL(style) {
const key = document
.querySelector("meta[name='carto-api-key']")
?.getAttribute("content");
const url = `https://{s}.basemaps.cartocdn.com/${style}/{z}/{x}/{y}{r}.png`;
return key ? `${url}?key=${encodeURIComponent(key)}` : url;
}

if (placesSection) initSection(placesSection, "places");
if (honeymoonSection) initSection(honeymoonSection, "honeymoon");
bindModal();
Expand Down Expand Up @@ -81,25 +89,19 @@
attributionControl: true,
});

L.tileLayer(
"https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
subdomains: "abcd",
maxZoom: 19,
},
).addTo(map);

L.tileLayer(
"https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png",
{
attribution: "",
subdomains: "abcd",
maxZoom: 19,
pane: "overlayPane",
},
).addTo(map);
L.tileLayer(cartoTileURL("light_nolabels"), {
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
subdomains: "abcd",
maxZoom: 19,
}).addTo(map);

L.tileLayer(cartoTileURL("light_only_labels"), {
attribution: "",
subdomains: "abcd",
maxZoom: 19,
pane: "overlayPane",
}).addTo(map);

entries = buildEntries(mode, items, pinsEl, map);

Expand Down
10 changes: 10 additions & 0 deletions templates/layout.templ
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package templates

import (
"os"
"strconv"
"strings"

Expand Down Expand Up @@ -35,6 +36,12 @@ func coordValue(coord float64) string {
return strconv.FormatFloat(coord, 'f', -1, 64)
}

// cartoAPIKey returns the publishable CARTO basemaps API key from the
// CARTO_API_KEY environment variable, or "" when unset (tiles stay keyless).
func cartoAPIKey() string {
return strings.TrimSpace(os.Getenv("CARTO_API_KEY"))
}

func publicImageURL(mediaID int) string {
if mediaID <= 0 {
return ""
Expand Down Expand Up @@ -66,6 +73,9 @@ templ Layout(title string, lang string, t i18n.T, ogMeta OGMeta, includeLeaflet
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-visual"/>
<title>{ title }</title>
<meta name="theme-color" content="#2A3439"/>
if cartoAPIKey() != "" {
<meta name="carto-api-key" content={ cartoAPIKey() }/>
}
<style>html,body{margin:0;background:#FCF8F3;color:#36454F;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}</style>
if ogMeta.Title != "" {
if ogMeta.Description != "" {
Expand Down
50 changes: 50 additions & 0 deletions templates/layout_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package templates

import (
"os"
"testing"
)

func TestCartoAPIKey(t *testing.T) {
tests := []struct {
name string
setup func(t *testing.T)
want string
}{
{
name: "unset",
setup: func(t *testing.T) {
t.Helper()
if err := os.Unsetenv("CARTO_API_KEY"); err != nil {
t.Fatal(err)
}
},
want: "",
},
{
name: "empty",
setup: func(t *testing.T) {
t.Helper()
t.Setenv("CARTO_API_KEY", "")
},
want: "",
},
{
name: "trims surrounding whitespace",
setup: func(t *testing.T) {
t.Helper()
t.Setenv("CARTO_API_KEY", " abc123 ")
},
want: "abc123",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.setup(t)
if got := cartoAPIKey(); got != tt.want {
t.Fatalf("cartoAPIKey() = %q, want %q", got, tt.want)
}
})
}
}
Loading