From e9e8fda6828fc55502ed9a05f1a4309ef99f698b Mon Sep 17 00:00:00 2001 From: sfomuseumbot Date: Thu, 23 May 2024 13:27:41 -0700 Subject: [PATCH] issue #2 - basic working runtime uris.js; still need to wrangle custom (un)marshaling for Root element --- app/server/handlers_www.go | 24 ++++++++ app/server/server.go | 2 + .../javascript/whosonfirst.spelunker.uris.js | 22 +++++++ uris.go | 2 +- www/uris.go | 60 +++++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 templates/javascript/whosonfirst.spelunker.uris.js create mode 100644 www/uris.go diff --git a/app/server/handlers_www.go b/app/server/handlers_www.go index 2e578ab..ff005e8 100644 --- a/app/server/handlers_www.go +++ b/app/server/handlers_www.go @@ -8,6 +8,7 @@ import ( "github.com/sfomuseum/go-http-opensearch" opensearch_http "github.com/sfomuseum/go-http-opensearch/http" + "github.com/whosonfirst/go-whosonfirst-spelunker-httpd/templates/javascript" "github.com/whosonfirst/go-whosonfirst-spelunker-httpd/www" ) @@ -19,6 +20,29 @@ func staticHandlerFunc(ctx context.Context) (http.Handler, error) { return http.StripPrefix(run_options.URIs.Static, fs_handler), nil } +func urisJSHandlerFunc(ctx context.Context) (http.Handler, error) { + + setupWWWOnce.Do(setupWWW) + + if setupWWWError != nil { + slog.Error("Failed to set up common configuration", "error", setupWWWError) + return nil, fmt.Errorf("Failed to set up common configuration, %w", setupWWWError) + } + + js_templates, err := javascript.LoadTemplates(ctx) + + if err != nil { + return nil, fmt.Errorf("Failed to load JavaScript templates, %w", err) + } + + opts := &www.URIsJSHandlerOptions{ + Templates: js_templates, + URIs: uris_table, + } + + return www.URIsJSHandler(opts) +} + func openSearchHandlerFunc(ctx context.Context) (http.Handler, error) { setupWWWOnce.Do(setupWWW) diff --git a/app/server/server.go b/app/server/server.go index e4a1b41..e3bac58 100644 --- a/app/server/server.go +++ b/app/server/server.go @@ -70,6 +70,8 @@ func RunWithOptions(ctx context.Context, opts *RunOptions, logger *slog.Logger) // Static assets run_options.URIs.Static: staticHandlerFunc, + // Run-time static assets + "/javascript/whosonfirst.spelunker.uris.js": urisJSHandlerFunc, // API/machine-readable run_options.URIs.ConcordanceNSFaceted: hasConcordanceFacetedHandlerFunc, diff --git a/templates/javascript/whosonfirst.spelunker.uris.js b/templates/javascript/whosonfirst.spelunker.uris.js new file mode 100644 index 0000000..ef22a32 --- /dev/null +++ b/templates/javascript/whosonfirst.spelunker.uris.js @@ -0,0 +1,22 @@ +{{ define "whosonfirst_spelunker_uris" -}} +var whosonfirst = whosonfirst || {}; +whosonfirst.spelunker = whosonfirst.spelunker || {}; + +whosonfirst.spelunker.uris = (function(){ + + var _table = {{ .Table }}; + + var self = { + + abs_root_url: function(){ + return "/"; + }, + + table: function(){ + return _table; + }, + }; + + return self; +})(); +{{ end -}} diff --git a/uris.go b/uris.go index 3faaa72..d1801a1 100644 --- a/uris.go +++ b/uris.go @@ -59,7 +59,7 @@ type URIs struct { SVG string `json:"svg"` SVGAlt []string `json:"svg_alt"` - Root *url.URL + Root *url.URL `json:"root_url"` } func (u *URIs) ApplyPrefix(prefix string) error { diff --git a/www/uris.go b/www/uris.go new file mode 100644 index 0000000..1b6845d --- /dev/null +++ b/www/uris.go @@ -0,0 +1,60 @@ +package www + +import ( + "encoding/json" + "fmt" + "log/slog" + "net/http" + "text/template" + + "github.com/whosonfirst/go-whosonfirst-spelunker-httpd" +) + +type URIsJSHandlerOptions struct { + Templates *template.Template + URIs *httpd.URIs +} + +type URIsJSVars struct { + Table string +} + +func URIsJSHandler(opts *URIsJSHandlerOptions) (http.Handler, error) { + + t := opts.Templates.Lookup("whosonfirst_spelunker_uris") + + if t == nil { + return nil, fmt.Errorf("Failed to locate 'whosonfirst_spelunker_uris' template") + } + + fn := func(rsp http.ResponseWriter, req *http.Request) { + + logger := slog.Default() + logger = logger.With("request", req.URL) + + enc_table, err := json.Marshal(opts.URIs) + + if err != nil { + logger.Error("Failed to marshal URIs table", "error", err) + http.Error(rsp, "Internal server error", http.StatusInternalServerError) + return + } + + vars := URIsJSVars{ + Table: string(enc_table), + } + + rsp.Header().Set("Content-type", "text/javascript") + err = t.Execute(rsp, vars) + + if err != nil { + logger.Error("Failed to execute template", "error", err) + http.Error(rsp, "Internal server error", http.StatusInternalServerError) + return + } + + return + } + + return http.HandlerFunc(fn), nil +}