{"id":21429016,"url":"https://github.com/notcoffee418/gowebsite-boilerplate","last_synced_at":"2026-01-03T07:37:11.628Z","repository":{"id":195247655,"uuid":"692522795","full_name":"NotCoffee418/GoWebsite-Boilerplate","owner":"NotCoffee418","description":"Boilerplate project for Go + HTML + PostgreSQL with routing and templates","archived":false,"fork":false,"pushed_at":"2024-04-19T12:18:36.000Z","size":381,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-23T08:16:23.769Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NotCoffee418.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-09-16T18:32:15.000Z","updated_at":"2023-09-28T17:55:56.000Z","dependencies_parsed_at":"2023-09-28T19:21:02.792Z","dependency_job_id":"dcce6417-2f76-477b-9cf4-40d04c1e518c","html_url":"https://github.com/NotCoffee418/GoWebsite-Boilerplate","commit_stats":null,"previous_names":["notcoffee418/gohtmxpgsql-boilerplate"],"tags_count":1,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FGoWebsite-Boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FGoWebsite-Boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FGoWebsite-Boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FGoWebsite-Boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NotCoffee418","download_url":"https://codeload.github.com/NotCoffee418/GoWebsite-Boilerplate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243940062,"owners_count":20372044,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-22T22:15:32.089Z","updated_at":"2026-01-03T07:37:11.587Z","avatar_url":"https://github.com/NotCoffee418.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Website Boilerplate Template\nThis template is a starting point for my Go web projects including my prefered technologies described below.  \nWhile it bends to my preferences, it is designed to be adaptable, expandable and easy to set up and modify to your needs.  \n\nAs of v0.1.0, it is also my first Go project, so it may not be perfect and major overhauls may happen.  \nContributions are welcome, but please keep in mind that this is a template, not a framework.\n\n\n## Features\n- Go webserver with Gin\n- HTMX with Go templates\n- HTMX WebSocket support\n- API handlers\n- PostgreSQL with sqlx\n- Tailwind CSS (compiled on startup)\n- Database migration system\n- Dockerfile with multi-stage build\n- Demo of all features\n\n## Template Setup\n\nAfter cloning the template, to finalize the setup, follow these quick steps:\n\n1. **Clone your repo:**\n    Replace `[YourUsername]` and `[YourRepoName]` with your GitHub username and repository name.\n\n    ```bash\n    git clone https://github.com/[YourUsername]/[YourRepoName].git\n    cd [YourRepoName]\n    ```\n\n2. **Run the setup script:**\n    This script essentially renames the project to your repository name.\n    ```bash\n    python repo-template-setup.py\n    ```\n\n3. **Commit and push:**\n\n    ```bash\n    git add -A\n    git commit -m \"Finalize setup\"\n    git push\n    ```\n\n\nThat's it! Your repo is now ready to use.\n\n## Requirements\n- [Go](https://golang.org/)\n- [PostgreSQL](https://www.postgresql.org/) or [Docker](https://www.docker.com/) (for database)\n- [Node.js](https://nodejs.org/en/) (for frontend dependencies)\n- [Python](https://www.python.org/) (for template setup script)\n- [VSCode](https://code.visualstudio.com/) (recommended)\n\n### Recommended VSCode Extensions\n- [Go](https://marketplace.visualstudio.com/items?itemName=golang.Go)\n- [gotemplate-syntax](https://marketplace.visualstudio.com/items?itemName=casualjim.gotemplate)\n\n## Try it out\nTo try the demo, you need to set up a database and .env, as the demo relies on it.  \n```bash\ncp .env.example .env\n```\nThen edit the .env file to match your database settings.\nYour `.env` file must be set up, since it will use the same variables for the app as setting up the database in docker.\n```bash\ndocker compose -f docker-compose.dev-db.yml up\n```\n\nYou can now build the application or run the release version:\n```bash\ngo build\n./GoWebsite-Boilerplate\n```\n\nView the demo at http://localhost:8080\n\n\n## Development\n\n### Change the layout\nThe base templateof  the application is defined in the `templates/layouts/default_base.html` file.  \nYou can change this as needed, but mind the imports and templating to maintain all functionality.  \n\n### Creating a page\n\n#####  Create a new html file in the `templates` directory\n##### Add the following to any page template:\n\n```html\n{{ template \"default_base.html\" . }}\n{{ define \"content\" }}\nYour page content should go here\n{{ end }}\n```\n\n##### Create a handler for the page in `./handlers` with this structure:\n```go\nvar db *sqlx.DB\n\n// HomePageHandler Implements types.HandlerRegistrar interface\ntype HomePageHandler struct{}\n\n// Initialize is called before the handler is registered\nfunc (h *HomePageHandler) Initialize(initContext *types.HandlerInitContext) {\n    db = initContext.DB\n}\n\n// Implements PageRouteRegistrar interface\nfunc (h *HomePageHandler) Handler(engine *gin.Engine) {\n    engine.GET(\"/\", h.get)\n}\n\nfunc (h *HomePageHandler) get(c *gin.Context) {\n    // Set SEO meta data\n    meta := \u0026page.PageMetaData{\n        Title:       \"Demo Home Page\",\n        Description: \"This is a demo home page showing off the boilerplate.\",\n    }\n\n    // Any additional data required by the page\n    data := \u0026map[string]interface{}{\n        \"Counter\": CounterData{\n            Value: 0,\n            Color: \"#fff\",\n        },\n    }\n\n    // Turn it into structured data\n    structuredData := page.StructurePageData(\u0026data, meta)\n\n    // Render page\n    c.HTML(http.StatusOK, \"home_page.html\", structuredData)\n}\n```\n\nYou can register multiple related handlers in one file. For more details see the  [Gin documentation](https://gin-gonic.com/docs/)\n\n##### Register the handler in `./handlers/registration.go`:\nAdd the handler to the `RouteHandlers` slice:\n```go\n\u0026yourmodule.SomePageHandler{},\n```\n\n### Creating an HTMX component\nThe instructions are the same as for creating a page, but you want to add the route in the relevant page or system's handler file.  \nAdditionally, htmx component templates should not include ```{{ template \"default_base.html\" . }}```.\n\nYou can still use `page.StructurePageData(data, nil)` without defining meta for between page and component, if the page loads the component as well.\n\n### API Handlers\nThey are registered in `./handlers/registration.go` alongside page handlers.  \nAPI handlers should return JSON data. Included in the package is a structured API response outputting responses like so:\n```json\n{\n    \"success\": true,\n    \"data\": {\n        \"someData\": \"Some data\"\n    }\n}\n```\nor for errors:\n\n```json\n{\n    \"success\": false,\n    \"error\": \"Error message\"\n}\n```\n\nYou can generate this data using `common.ApiResponseFactory.Ok(data)` and `common.ApiResponseFactory.Error(err)` respectively.\n\nAn API handler will generally look like this:\n```go\nvar db *sqlx.DB\n\n// HomeApiHandler Implements types.HandlerRegistrar interface\ntype HomeApiHandler struct{}\n\n// HomePageData is the response for the time call\ntype HomePageData struct {\n    Time string `json:\"time\"`\n}\n\n// Initialize is called before the handler is registered\nfunc (h *HomeApiHandler) Initialize(initContext *types.HandlerInitContext) {\n    db = initContext.DB\n}\n\nfunc (h *HomeApiHandler) Handler(engine *gin.Engine) {\n    engine.GET(\"/api/home/get-server-time\", h.get)\n}\n\nfunc (h *HomeApiHandler) get(c *gin.Context) {\n    timeStr := time.Now().Format(\"2006-01-02 15:04:05\")\n    resp := common.ApiResponseFactory.Ok(\n        \u0026HomePageData{Time: timeStr})\n\n    // Render page\n    c.JSON(http.StatusOK, resp)\n}\n```\n\n## Static and dynamic assets\nThese are files that are served directly by the webserver in slightly different ways.\n\n### Static Assets\n* Repo path: `./assets/static/`\n* Web path: `/`\n* Embedded: Yes\n* Ideal for: Small, commonly used files\n\nStatic assets are embedded in the executable, this means they can be served faster, but they cannot be changed without recompiling the application.\nIt also means it's not suitable for large files.  \nIt's ideal for small files like favicons, logos, javascript libraries, etc.  \nThey each get their own handler registered directly at `/`.\n\n### Dynamic Assets\n* Repo path: `./assets/dynamic/`\n* Web path: `/dynamic/`\n* Embedded: No\n* Ideal for: Large files, files that change often\n\nDynamic assets are not embedded in the executable, this means they can be changed without recompiling the application, but they are served slightly slower.  \nIt's ideal for large files like images, videos, etc. assuming they are not hosted on a CDN.\nThey do not have direct handlers, but instead get served as fallback before the 404 handler is called.\n\nWe also use this to serve compiled Tailwind files, since they are generated on application startup.  \nYou can change this behavior in by setting up your own pre-compile postcss call and disabling `config.MinifyCss` in `config/config.go`.\n\n## Default Template Definitions\nThese ensure that all pages have the required blocks and that the layout is loaded correctly.  \nYou can add additional blocks to the layout as needed in `config/template_definitions.go`.  \nThe default definitions are:\n\n- `content`: Each page expects a `content` block to be defined. HTMX components do not use this block.\n- `scripts`: Optional, at the bottom of the page. Can be used to add additional scripts to the page. `\u003cscript\u003e` tags are required.\n- `head`: Optional, will be loaded in `\u003chead\u003e` of the page.\n- `page_title`: Will be used as the page title. Defaults to website name.\n\n\n## Utility Functions","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotcoffee418%2Fgowebsite-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotcoffee418%2Fgowebsite-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotcoffee418%2Fgowebsite-boilerplate/lists"}