Skip to content

Replace go-martini with chi router#39

Merged
renecannao merged 1 commit intomasterfrom
issue35-replace-martini
Mar 24, 2026
Merged

Replace go-martini with chi router#39
renecannao merged 1 commit intomasterfrom
issue35-replace-martini

Conversation

@renecannao
Copy link
Copy Markdown

@renecannao renecannao commented Mar 24, 2026

Summary

  • Migrate the entire HTTP layer from the deprecated go-martini framework to the chi router (github.com/go-chi/chi/v5)
  • Replace all martini dependency injection with standard http.HandlerFunc(w, r) signatures across 100+ API routes, web routes, and agent routes
  • Remove 5 martini-related dependencies (go-martini, martini-contrib/auth, martini-contrib/gzip, martini-contrib/render, codegangsta/inject)

Details

This is a framework swap that preserves all existing URL paths and API behavior:

  • Routing: m.Get("/api/path", handler) replaced with r.Get("/api/path", handler) using chi
  • URL params: Martini :param style replaced with chi {param} style
  • Dependency injection: Martini's params martini.Params, r render.Render, req *http.Request, user auth.User replaced with standard w http.ResponseWriter, r *http.Request
  • Auth middleware: Custom BasicAuthMiddleware and MultiAuthMiddleware replace martini-contrib/auth, storing user in request context
  • Template rendering: New lightweight renderJSON/renderHTML/renderRedirect helpers replace martini-contrib/render
  • Gzip: chi's middleware.Compress replaces martini-contrib/gzip
  • Raft proxy: Converted from martini handler to chi middleware pattern
  • SSL OU verification: VerifyOUs converted from martini.Handler to standard func(http.Handler) http.Handler middleware

Closes #35

Test plan

  • go build succeeds
  • go test ./go/http/... passes (all 7 tests)
  • go test -vet=off ./go/... passes (pre-existing vet issues in other packages unrelated to this change)
  • No remaining references to martini in Go source files
  • All martini dependencies removed from go.mod
  • Manual smoke test: start orchestrator and verify web UI loads
  • Manual smoke test: verify API endpoints respond correctly
  • Manual smoke test: verify static file serving works

Summary by CodeRabbit

  • Refactor
    • Migrated HTTP server framework from Martini to Chi router for improved performance and maintainability.
    • Updated authentication and middleware infrastructure to leverage Chi's modern patterns.
    • Enhanced request routing and static file serving with streamlined implementation.

Migrate the entire HTTP layer from the deprecated go-martini framework to
the chi router (github.com/go-chi/chi/v5). This is a framework swap that
preserves all existing URL paths and behavior.

Key changes:
- Replace martini.Classic() with chi.NewRouter() + standard middleware
- Replace martini dependency injection with standard http.HandlerFunc(w, r)
- Replace martini-contrib/render with lightweight renderJSON/renderHTML helpers
- Replace martini-contrib/auth with custom BasicAuth/MultiAuth middleware
- Replace martini-contrib/gzip with chi middleware.Compress
- Replace martini URL params (:param) with chi params ({param})
- Replace params["x"] with chi.URLParam(r, "x")
- Replace martini's raft reverse proxy handler with chi middleware pattern
- Update ssl.VerifyOUs to return standard http middleware instead of martini.Handler
- Remove go-martini, martini-contrib/*, and codegangsta/inject dependencies

Closes #35
Copilot AI review requested due to automatic review settings March 24, 2026 00:54
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7fbfed3f-80c9-4963-a758-6a7e7528b3dc

📥 Commits

Reviewing files that changed from the base of the PR and between 737d999 and cfe5815.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (91)
  • go.mod
  • go/app/http.go
  • go/http/agents_api.go
  • go/http/api.go
  • go/http/api_test.go
  • go/http/httpbase.go
  • go/http/raft_reverse_proxy.go
  • go/http/render.go
  • go/http/web.go
  • go/ssl/ssl.go
  • vendor/github.com/codegangsta/inject/.gitignore
  • vendor/github.com/codegangsta/inject/LICENSE
  • vendor/github.com/codegangsta/inject/README.md
  • vendor/github.com/codegangsta/inject/inject.go
  • vendor/github.com/codegangsta/inject/update_readme.sh
  • vendor/github.com/go-chi/chi/v5/.gitignore
  • vendor/github.com/go-chi/chi/v5/CHANGELOG.md
  • vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md
  • vendor/github.com/go-chi/chi/v5/LICENSE
  • vendor/github.com/go-chi/chi/v5/Makefile
  • vendor/github.com/go-chi/chi/v5/README.md
  • vendor/github.com/go-chi/chi/v5/SECURITY.md
  • vendor/github.com/go-chi/chi/v5/chain.go
  • vendor/github.com/go-chi/chi/v5/chi.go
  • vendor/github.com/go-chi/chi/v5/context.go
  • vendor/github.com/go-chi/chi/v5/middleware/basic_auth.go
  • vendor/github.com/go-chi/chi/v5/middleware/clean_path.go
  • vendor/github.com/go-chi/chi/v5/middleware/compress.go
  • vendor/github.com/go-chi/chi/v5/middleware/content_charset.go
  • vendor/github.com/go-chi/chi/v5/middleware/content_encoding.go
  • vendor/github.com/go-chi/chi/v5/middleware/content_type.go
  • vendor/github.com/go-chi/chi/v5/middleware/get_head.go
  • vendor/github.com/go-chi/chi/v5/middleware/heartbeat.go
  • vendor/github.com/go-chi/chi/v5/middleware/logger.go
  • vendor/github.com/go-chi/chi/v5/middleware/maybe.go
  • vendor/github.com/go-chi/chi/v5/middleware/middleware.go
  • vendor/github.com/go-chi/chi/v5/middleware/nocache.go
  • vendor/github.com/go-chi/chi/v5/middleware/page_route.go
  • vendor/github.com/go-chi/chi/v5/middleware/path_rewrite.go
  • vendor/github.com/go-chi/chi/v5/middleware/profiler.go
  • vendor/github.com/go-chi/chi/v5/middleware/realip.go
  • vendor/github.com/go-chi/chi/v5/middleware/recoverer.go
  • vendor/github.com/go-chi/chi/v5/middleware/request_id.go
  • vendor/github.com/go-chi/chi/v5/middleware/request_size.go
  • vendor/github.com/go-chi/chi/v5/middleware/route_headers.go
  • vendor/github.com/go-chi/chi/v5/middleware/strip.go
  • vendor/github.com/go-chi/chi/v5/middleware/sunset.go
  • vendor/github.com/go-chi/chi/v5/middleware/supress_notfound.go
  • vendor/github.com/go-chi/chi/v5/middleware/terminal.go
  • vendor/github.com/go-chi/chi/v5/middleware/throttle.go
  • vendor/github.com/go-chi/chi/v5/middleware/timeout.go
  • vendor/github.com/go-chi/chi/v5/middleware/url_format.go
  • vendor/github.com/go-chi/chi/v5/middleware/value.go
  • vendor/github.com/go-chi/chi/v5/middleware/wrap_writer.go
  • vendor/github.com/go-chi/chi/v5/mux.go
  • vendor/github.com/go-chi/chi/v5/pattern.go
  • vendor/github.com/go-chi/chi/v5/pattern_fallback.go
  • vendor/github.com/go-chi/chi/v5/tree.go
  • vendor/github.com/go-martini/martini/.gitignore
  • vendor/github.com/go-martini/martini/LICENSE
  • vendor/github.com/go-martini/martini/README.md
  • vendor/github.com/go-martini/martini/env.go
  • vendor/github.com/go-martini/martini/go_version.go
  • vendor/github.com/go-martini/martini/logger.go
  • vendor/github.com/go-martini/martini/martini.go
  • vendor/github.com/go-martini/martini/recovery.go
  • vendor/github.com/go-martini/martini/response_writer.go
  • vendor/github.com/go-martini/martini/return_handler.go
  • vendor/github.com/go-martini/martini/router.go
  • vendor/github.com/go-martini/martini/static.go
  • vendor/github.com/go-martini/martini/wercker.yml
  • vendor/github.com/martini-contrib/auth/README.md
  • vendor/github.com/martini-contrib/auth/basic.go
  • vendor/github.com/martini-contrib/auth/util.go
  • vendor/github.com/martini-contrib/auth/wercker.yml
  • vendor/github.com/martini-contrib/gzip/LICENSE
  • vendor/github.com/martini-contrib/gzip/README.md
  • vendor/github.com/martini-contrib/gzip/gzip.go
  • vendor/github.com/martini-contrib/gzip/wercker.yml
  • vendor/github.com/martini-contrib/render/LICENSE
  • vendor/github.com/martini-contrib/render/README.md
  • vendor/github.com/martini-contrib/render/render.go
  • vendor/github.com/martini-contrib/render/wercker.yml
  • vendor/github.com/oxtoacart/bpool/LICENSE
  • vendor/github.com/oxtoacart/bpool/README.md
  • vendor/github.com/oxtoacart/bpool/bpool.go
  • vendor/github.com/oxtoacart/bpool/bufferpool.go
  • vendor/github.com/oxtoacart/bpool/bytepool.go
  • vendor/github.com/oxtoacart/bpool/byteslice.go
  • vendor/github.com/oxtoacart/bpool/sizedbufferpool.go
  • vendor/modules.txt

📝 Walkthrough

Walkthrough

This pull request migrates the HTTP layer from the unmaintained Martini framework to Chi v5, a lightweight, stdlib-compatible router. The migration includes replacing Martini route handlers, middleware, and dependency injection with Chi-style handlers, new authentication and rendering middlewares, and updated request parameter extraction patterns throughout the HTTP API and web UI handlers.

Changes

Cohort / File(s) Summary
Dependency Updates
go.mod, vendor/modules.txt
Removed Martini (github.com/go-martini/martini), Martini middleware (martini-contrib/auth, gzip, render), and related dependencies (codegangsta/inject, oxtoacart/bpool). Added Chi v5.2.5 as the primary HTTP router.
Server Setup & Middleware
go/app/http.go, go/http/httpbase.go
Replaced Martini classic app initialization with Chi router in both standardHttp and agentsHttp. Introduced BasicAuthMiddleware and MultiAuthMiddleware for authentication. Removed Martini-specific environment configuration and added Chi middleware for panic recovery and request logging.
Response & Template Rendering
go/http/render.go
New file implementing renderJSON, renderHTML, and renderRedirect helpers with template caching and content-type management, replacing Martini's render middleware injection.
API Handler Migrations
go/http/agents_api.go
Converted six agent API handlers from Martini params/render injection to Chi-style (http.ResponseWriter, *http.Request) signatures. Updated URL parameter extraction to use chi.URLParam and explicit response writing via renderJSON.
Web Handler Migrations
go/http/web.go
Converted 22 web UI handlers from Martini to Chi patterns. Refactored route registration to use Chi router with {param} syntax. Updated request parameter access and response rendering calls to use new project-level helpers.
Reverse Proxy & SSL
go/http/raft_reverse_proxy.go, go/ssl/ssl.go
Converted Martini-specific handlers to Chi-compatible middleware factories. Updated raft reverse proxy to middleware pattern; replaced VerifyOUs handler with VerifyOUsMiddleware.
Test Updates
go/http/api_test.go
Updated test router initialization from Martini to Chi.
Removed Vendor Code
vendor/github.com/codegangsta/inject/*, vendor/github.com/go-martini/martini/*, vendor/github.com/martini-contrib/{auth,gzip,render}/*, vendor/github.com/oxtoacart/bpool/*
Deleted entire Martini framework, inject, and bpool implementations as dependencies are no longer needed.
Added Vendor Code
vendor/github.com/go-chi/chi/v5/*
Added complete Chi v5 router library including core routing (chi.go, mux.go, tree.go), middleware ecosystem (compress, logger, recoverer, timeout, etc.), and context/parameter management utilities.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Middleware as Chi Middleware Stack
    participant Router as Chi Router/Mux
    participant Handler as HTTP Handler
    participant RenderHelper as Render Helpers

    Client->>Middleware: HTTP Request
    Middleware->>Middleware: RequestID, Logger, Recoverer, Auth
    Middleware->>Router: Pass Request (authenticated)
    Router->>Router: Match Pattern & Extract URLParams
    Router->>Handler: Route to Matched Handler
    Handler->>Handler: Extract params via chi.URLParam()
    Handler->>Handler: Process Business Logic
    Handler->>RenderHelper: renderJSON(w, status, data)
    RenderHelper->>Handler: JSON Encoded Response
    Handler->>Client: HTTP Response with Status & Body
    Client-->>Middleware: Response Complete
    Middleware->>Client: Log Response (status, duration)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 Hopping from Martini to Chi,
The framework's no longer shy—
With stdlib-aligned grace,
We've run a fine race,
From dusty old bottles to dry! 🏃‍♂️

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue35-replace-martini

@renecannao renecannao merged commit e08f4b6 into master Mar 24, 2026
3 of 8 checks passed
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on modernizing the orchestrator's HTTP routing and middleware handling by replacing the outdated go-martini framework with the chi router. This transition involves significant code refactoring to align with standard net/http practices, enhancing maintainability and performance while preserving existing API behavior. The changes include custom authentication middleware, streamlined template rendering, and updated compression and SSL verification implementations.

Highlights

  • Framework Migration: Migrated the HTTP layer from the deprecated go-martini framework to the chi router (github.com/go-chi/chi/v5).
  • Dependency Injection Replacement: Replaced Martini dependency injection with standard http.HandlerFunc(w, r) signatures across API, web, and agent routes.
  • Dependency Removal: Removed 5 Martini-related dependencies, including go-martini, martini-contrib/auth, martini-contrib/gzip, martini-contrib/render, and codegangsta/inject.
  • Authentication Middleware: Implemented custom BasicAuthMiddleware and MultiAuthMiddleware to replace martini-contrib/auth, storing user information in the request context.
  • Template Rendering: Introduced lightweight renderJSON, renderHTML, and renderRedirect helpers to replace martini-contrib/render.
  • Gzip Compression: Utilized chi's middleware.Compress to replace martini-contrib/gzip for response compression.
  • Raft Proxy Conversion: Converted the Raft proxy from a Martini handler to a Chi middleware pattern.
  • SSL OU Verification: Transformed VerifyOUs from martini.Handler to standard func(http.Handler) http.Handler middleware.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the project’s HTTP layer from the deprecated go-martini framework to the chi router, replacing Martini DI-style handlers and middleware with standard net/http handlers and chi middleware while removing martini-related dependencies.

Changes:

  • Replace martini routing/middleware with github.com/go-chi/chi/v5 for API, web UI, and agent endpoints.
  • Introduce new auth, raft reverse-proxy, TLS OU-verification middleware, and lightweight JSON/HTML/redirect render helpers.
  • Update vendored dependencies to remove martini-related packages and add chi.

Reviewed changes

Copilot reviewed 9 out of 92 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
go/app/http.go Switch server setup to chi router and chi middleware; update auth/static/TLS middleware wiring.
go/http/httpbase.go Replace martini auth user injection with request-context user storage; add Basic/Multi auth middleware and chi param helpers.
go/http/render.go Add new JSON/HTML/redirect rendering helpers and template caching.
go/http/raft_reverse_proxy.go Convert raft leader proxying from martini handler to standard middleware.
go/ssl/ssl.go Convert OU verification from martini handler to standard middleware.
go/http/agents_api.go Migrate agents API handlers from martini DI/render to http.ResponseWriter + *http.Request + chi params.
go/http/api_test.go Update tests to use chi router registration.
go.mod Remove martini-related deps; add github.com/go-chi/chi/v5.
go.sum Update sums to reflect dependency changes.
vendor/modules.txt Vendor manifest updates (remove martini deps, add chi).
vendor/... Vendored dependency tree updated (remove martini/auth/gzip/render/inject/bpool, add chi + middleware, and associated files).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread go/http/agents_api.go
func (this *HttpAgentsAPI) SetHostAttribute(params martini.Params, r render.Render, req *http.Request) {
err := attributes.SetHostAttributes(params["host"], params["attrVame"], params["attrValue"])
func (this *HttpAgentsAPI) SetHostAttribute(w http.ResponseWriter, r *http.Request) {
err := attributes.SetHostAttributes(chi.URLParam(r, "host"), chi.URLParam(r, "attrVame"), chi.URLParam(r, "attrValue"))
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL param placeholder/key attrVame looks like a typo (should likely be attrName). With chi, the placeholder name is internal-only and can be corrected without changing the external URL path structure. Renaming it would reduce confusion and prevent propagating the typo into new code.

Suggested change
err := attributes.SetHostAttributes(chi.URLParam(r, "host"), chi.URLParam(r, "attrVame"), chi.URLParam(r, "attrValue"))
err := attributes.SetHostAttributes(chi.URLParam(r, "host"), chi.URLParam(r, "attrName"), chi.URLParam(r, "attrValue"))

Copilot uses AI. Check for mistakes.
Comment thread go/app/http.go
m := martini.Classic()
router := chi.NewRouter()

// Middleware
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new middleware stack uses chi/middleware.Logger, which logs r.RemoteAddr directly. Previously martini's logger preferred X-Real-IP/X-Forwarded-For, so deployments behind a reverse proxy may lose real client IPs in logs. If you still expect the old behavior, add chi/middleware.RealIP early (or implement an equivalent proxy-aware logger) and document the trust assumptions for these headers.

Suggested change
// Middleware
// Middleware
router.Use(chimiddleware.RealIP)

Copilot uses AI. Check for mistakes.
Comment thread go/http/render.go
Comment on lines +56 to +61
layoutPath := filepath.Join(templateDir, layoutFile+".tmpl")
tmplPath := filepath.Join(templateDir, name+".tmpl")
t, err := template.ParseFiles(layoutPath, tmplPath)
if err != nil {
return nil, err
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

layout.tmpl uses the {{yield}} helper, but getTemplate() parses templates without registering yield (or current) funcs. This will cause template parsing to fail and the web UI to return 500 for every page. Add the helper funcs to the template FuncMap before parsing (and ensure the per-request yield implementation renders the requested page template).

Copilot uses AI. Check for mistakes.
Comment thread go/http/render.go
Comment on lines +78 to +82
w.Header().Set("Content-Type", "text/html; charset=UTF-8")
w.WriteHeader(status)
if err := t.Execute(w, data); err != nil {
log.Errorf("Error executing template %s: %+v", name, err)
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renderHTML writes headers/status before executing the template. If template execution fails mid-stream, the response may be partially written and cannot be converted into a clean 500. Consider rendering into a buffer first (as the old martini renderer did) and only writing headers/body after successful execution.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and well-executed migration from the deprecated go-martini framework to chi. The changes are extensive, touching the entire HTTP layer, but appear to be handled correctly by replacing dependency injection with standard http.HandlerFunc signatures and context-based value passing. The introduction of custom middleware for authentication and helper functions for rendering standardizes the new approach. I've found a couple of issues: one critical bug that would cause a runtime panic, and one area for performance improvement in template caching. Overall, this is a great improvement that modernizes the codebase and removes unmaintained dependencies.

Comment thread go/http/web.go

// go-metrics
m.Get(this.URLPrefix+"/debug/metrics", exp.ExpHandler(metrics.DefaultRegistry))
router.Get(this.URLPrefix+"/debug/metrics", exp.ExpHandler(metrics.DefaultRegistry).(http.HandlerFunc))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This line will cause a runtime panic. exp.ExpHandler returns an http.Handler, but not an http.HandlerFunc. The type assertion .(http.HandlerFunc) will fail. You should use router.Handle which accepts an http.Handler.

Suggested change
router.Get(this.URLPrefix+"/debug/metrics", exp.ExpHandler(metrics.DefaultRegistry).(http.HandlerFunc))
router.Handle(this.URLPrefix+"/debug/metrics", exp.ExpHandler(metrics.DefaultRegistry))

Comment thread go/http/render.go
Comment on lines +48 to +67
func getTemplate(name string) (*template.Template, error) {
templateCache.RLock()
if t, ok := templateCache.m[name]; ok {
templateCache.RUnlock()
return t, nil
}
templateCache.RUnlock()

layoutPath := filepath.Join(templateDir, layoutFile+".tmpl")
tmplPath := filepath.Join(templateDir, name+".tmpl")
t, err := template.ParseFiles(layoutPath, tmplPath)
if err != nil {
return nil, err
}

templateCache.Lock()
templateCache.m[name] = t
templateCache.Unlock()
return t, nil
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation of getTemplate has a race condition that can lead to inefficient template parsing. If multiple goroutines request the same uncached template simultaneously, they will all parse the template file, with only the last one's result being stored. This can be optimized to avoid redundant work.

func getTemplate(name string) (*template.Template, error) {
	templateCache.RLock()
	t, ok := templateCache.m[name]
	templateCache.RUnlock()
	if ok {
		return t, nil
	}

	templateCache.Lock()
	defer templateCache.Unlock()
	// Re-check for the template, as another goroutine may have added it
	// while we were waiting for the lock.
	if t, ok := templateCache.m[name]; ok {
		return t, nil
	}

	layoutPath := filepath.Join(templateDir, layoutFile+".tmpl")
	tmplPath := filepath.Join(templateDir, name+".tmpl")
	t, err := template.ParseFiles(layoutPath, tmplPath)
	if err != nil {
		return nil, err
	}

	templateCache.m[name] = t
	return t, nil
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 3.6: Replace go-martini with modern web framework

2 participants