🚀 Streamline Website Creation: Golang, Markdown, Tailwind, Alpine.js, Templ
- Inspired by Nuxt Content
Where we're bringing simplicity and efficiency back to web development. Our journey began with a realization: creating simple web pages shouldn't require complex solutions. This project is our exploration into making web development straightforward, focusing on static sites with minimal updates.
Why Not WordPress?
For many, WordPress is the go-to solution for creating websites with a handful of pages and posts. However, it's like having a swimming pool guard at the Olympics: unnecessary for the skilled and an overkill for the simple needs. Our project seeks to avoid the overhead of databases for content that rarely changes, optimizing both development and page load times.
Introduction to Our Approach
Inspired by the elegance of Nuxt and the simplicity of Vue, we found a way to streamline web development without sacrificing performance. Our goal was to develop a web application that is not only quick to develop but also exceptionally fast for the end-user.
The Turning Point
While experimenting with a Nuxt-driven site, the resource consumption for a low-traffic scenario was notably high. This observation led us to rethink our approach and explore alternatives that maintain simplicity without the resource overhead.
Our Solution: A Golang Web App
We developed a lightweight web app in Golang, focusing on the following features:
- Content-driven: Dynamically serves content based on the URI, checking for corresponding .md or .html files or folders.
- Integrated Templating and Markdown Rendering: Utilizes Go's
http.ServeMux
, a powerful template engine, and Goldmark for markdown rendering. - Performance: Achieves a Google Lighthouse score of 100, ensuring top-tier user experience.
Why Golang?
Choosing Golang for this project was strategic. Its performance in terms of resource management is unparalleled, especially when compared to more traditional choices for web development in similar scenarios. Our app demonstrates that even for simple sites, efficiency doesn't have to be compromised.
Features
- Automatic Routing: Based on file and folder names within the content directory.
- Markdown and HTML Support: Flexibility in content creation. Using goldmark markdown.
- High Performance: Optimized for speed, achieving perfect performance scores.
- Templ engine: for a more natural way of writing markup. Templ.
- Tailwind CSS and Alpine.js: For a modern, responsive design without the bloat.
Getting Started
To set up this project locally and start contributing, follow these steps:
-
Clone the repository to your local machine.
git clone git@github.com:mediamagi/magicms-medium.git
-
Install Golang if it's not already installed on your system.
-
Environment Setup:
-
Copy
example.env
to.env
in the project root. This file contains necessary environment variables for running the application.cp example.env .env
-
-
Compile the Application:
- Navigate to the project directory and run
go run main.no
to compile and run the application.
- Navigate to the project directory and run
-
View the output:
- Navigate to
localhost:3000
in your web browser to view the site. It will look for an index.md or index.html in the content folder to render. Make sure you have an index file.
- Navigate to
-
Working with CSS:
-
To automatically compile your Tailwind CSS, use the following command:
npx tailwindcss -i ./src/input.css -o ./static/css/styles.css --watch
This command watches for changes in your CSS and automatically recompiles the Tailwind output file.
-
-
Generating Templates:
-
For dynamic template generation, use the
templ generate --watch
command. This will monitor your template files for changes and automatically regenerate them as needed.templ generate --watch
-
(The rest of the content is injected as a related file to index.md)
Adding meta title and description in the markdown file
---
title: This is the title
description: This is the description
---
Add the meta fields you need, and grab them using the following syntaxt in main.go
metaData["{field_name}"].(string)
Handling Related Content in Markdown Files
Our platform supports associating related content with Markdown documents through the use of a relation
field within the document's front matter. This allows for the seamless integration of additional resources, enhancing the richness and utility of your content.
Specifying Related Content
To specify related content, include the relation
field in the YAML front matter of your Markdown document. The related content must be located within the same directory as the referring document. Here’s how you can specify a related HTML file:
---
relation: _additionalInfo.html
---
Naming Conventions and Access
- Files named with a leading underscore (
_
) are treated specially. They are meant to be included as part of another document and are not directly accessible via a URL. This convention helps in organizing your content and keeping auxiliary files hidden. - If you wish for the related file to be accessible as standalone content, do not prefix the filename with
_
. This makes the file directly accessible through its URL, allowing it to serve as both related content and a standalone resource.
Examples
Including an HTML File
For Markdown documents that require supplementary HTML content to be displayed alongside the Markdown-rendered content, specify the HTML file using the relation
field. The content of this file will be rendered in place when the Markdown document is accessed. Remember, if the filename starts with _
, the content is intended for inclusion and not direct access:
---
relation: _contactForm.html
---
Making Related Content Accessible
If you have a related document that should also be accessible on its own, simply ensure it does not begin with _
. This is useful for supplementary guides, forms, or any content that serves a dual purpose—both as standalone and as related content.
---
relation: termsOfService.html
---
Render meta data in a html file:
<!-- Meta:
title: Example Title
description: Example Description
relation: _ar.md
-->
If the related file is inside a folder, add it like this
<!-- Meta:
relation: foldername/_ar.md
-->