- Home page
- Component
- Layout
- Structure
- Go Code
@use('layouts/base')
@insert('title', 'Book Store')
@insert('content')
<h1 class="text-2xl font-bold">Welcome to the Book Store</h1>
<p class="opacity-70 mb-5">See the list of our books</p>
@if(books.len() > 0)
<div>
@each(book in books)
@component('components/book', { book })
@end
</div>
@else
<p>No books found</p>
@end
@end
<div class="flex justify-between items-center gap-3 p-5 odd:bg-gray-100 rounded-md">
<div class="flex items-center gap-5">
<img
src="{{ book.image }}"
alt="{{ book.title }}"
class="w-20 rounded-md shadow-md"
>
<div>
<h3 class="text-xl">{{ book.title }}</h3>
<p class="opacity-70">{{ book.author }}</p>
</div>
</div>
<button class="bg-green-600 text-white px-5 py-2 rounded-md shadow-md cursor-pointer">
Order
</button>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<title>@reserve('title') | Books Store</title>
</head>
<body class="max-w-[900px] my-0 mx-auto p-4">
<main>
@reserve('content')
</main>
</body>
</html>
templates/
├── layouts/
│ └── base.tw
│
├── components/
│ └── book.tw
│
├── views/
│ └── home.tw
│
└── error-page.tw
package main
import (
"fmt"
"net/http"
"github.com/textwire/textwire/v2"
"github.com/textwire/textwire/v2/config"
)
var tpl *textwire.Template
func main() {
var err error
tpl, err = textwire.NewTemplate(&config.Config{
DebugMode: true,
})
if err != nil {
fmt.Println(err)
}
http.HandleFunc("/", homeHandler)
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Println(err)
}
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
vars := map[string]any{
"books": []struct{ Title, Author, Image string }{
{"The Great Gatsby", "F. Scott Fitzgerald", "https://placehold.co/400"},
{"To Kill a Mockingbird", "Harper Lee", "https://placehold.co/400"},
{"1984", "George Orwell", "https://placehold.co/400"},
{"Pride and Prejudice", "Jane Austen", "https://placehold.co/400"},
{"The Catcher in the Rye", "J.D. Salinger", "https://placehold.co/400"},
},
}
err := tpl.Response(w, "views/home", vars)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
Security
Textwire is designed to be secure by default, preventing code injection attacks when printing user-generated content
Flexibility
Textwire allows you to define custom functions and components, giving you the flexibility to create complex templates with ease
Performance
Textwire is fast and has a low memory footprint, making it load pages quickly. The parsing is done at application startup, so there is no overhead during runtime
Error handling
Textwire provides detailed error messages with line numbers and file names, making it easier to debug your templates
Syntax Highlighting
You get syntax highlighting and other features for Textwire using the Neovim plugin and VSCode extension
Good documentation
Textwire has a comprehensive documentation that covers all the features and provides examples to help you get started
