README
¶
Chirper: A Simple Real-Time Twitter Clone
The example demonstrates progressive enhancement, form validation, and real-time changes.
Table of Contents
- Prerequisites
- Step 1: Setting Up the Project
- Step 2: Features Overview
- Step 3: Testing the Application
- Conclusion
- References
Prerequisites
Before starting, ensure you have the following installed:
Step 1: Setting Up the Project
-
Clone the Fir repository:
git clone https://github.com/livefir/fir.git -
Navigate to the Chirper example directory:
cd fir/examples/chirper -
Ensure you have the required dependencies installed:
- Install Bolthold for database storage.
- Install Go (1.18 or later).
-
Run the application:
go run . -
Open your browser and navigate to:
- http://localhost:9867/nojs for the plain HTML version.
- http://localhost:9867 for the enhanced JavaScript version.
Step 2: Features Overview
1. Progressive Enhancement
Chirper supports both a plain HTML version (for browsers without JavaScript) and an enhanced version with JavaScript for real-time updates.
Plain HTML Version (index_no_js.html)
- Route: Handled by the
NoJSIndexfunction inindex.go. - How it works:
- The
OnLoadfunction (loadChirps) is invoked automatically when the page loads. - Chirps are fetched from the database and rendered using the
chirpsdata. - Errors during loading are displayed using
{{ fir.Error "onload" }}.
- The
Enhanced Version (index.html)
- Route: Handled by the
Indexfunction inindex.go. - How it works:
- Uses Alpine.js and Fir's JavaScript plugin to enable real-time updates.
- Events like creating, liking, and deleting chirps are handled without reloading the page.
2. Listing Chirps
- Chirps are fetched from the database using the
loadChirpsfunction inindex.go. - The returned data (
ctx.Data) is used to render the page. - Errors during loading are displayed using
{{ fir.Error "onload" }}.
Plain HTML Example:
<p>
{{ fir.Error "onload" }}
</p>
<div>
{{ range .chirps }}
<section>
<blockquote>{{ .Body }}</blockquote>
<footer>
<button formaction="?event=like-chirp" type="submit">♥ {{ .LikesCount }}</button>
<button formaction="?event=delete-chirp" type="submit">✕</button>
</footer>
</section>
{{ end }}
</div>
3. Creating Chirps
Plain HTML Version
- Chirps are created by submitting a form with the action
?event=create-chirp. - The
createChirpfunction inindex.go:- Validates the chirp body (minimum 3 characters).
- Uses
RouteContext.Bindto bind form data and return errors. - Errors are displayed using
{{ fir.Error "create-chirp.body" }}.
Example:
<form method="post" action="?event=create-chirp">
<textarea name="body" placeholder="a new chirp" rows="4" cols="100"></textarea>
<p>{{ fir.Error "create-chirp.body" }}</p>
<button type="submit">Chirp</button>
</form>
Enhanced Version
- Prevents page reloads using Alpine.js and Fir's
$fir.submit()magic function. - Resets the form on success using
@fir:create-chirp:ok.nohtml="$el.reset()". - Example:
<form
method="post"
action="?event=create-chirp"
@submit.prevent="$fir.submit()"
@fir:create-chirp:ok.nohtml="$el.reset()">
<textarea name="body" placeholder="a new chirp" rows="4" cols="100"></textarea>
<p @fir:create-chirp:error="$fir.replace()">{{ fir.Error "create-chirp.body" }}</p>
<button type="submit">Chirp</button>
</form>
4. Liking and Deleting Chirps
Plain HTML Version
- Chirps can be liked or deleted using forms with actions
?event=like-chirpand?event=delete-chirp. - Example:
<form method="post">
<button formaction="?event=like-chirp" type="submit">♥ {{ .LikesCount }}</button>
<button formaction="?event=delete-chirp" type="submit">✕</button>
</form>
Enhanced Version
- Real-time updates are enabled using Alpine.js and Fir's magic functions:
@fir:like-chirp:ok="$fir.replace()"updates the like count.@fir:delete-chirp:ok.nohtml="$fir.removeEl()"removes the chirp.
Example:
<section fir-key="{{ .ID }}" @fir:delete-chirp:ok.nohtml="$fir.removeEl()">
<form method="post" @submit.prevent="$fir.submit()">
<blockquote>
{{ .Body }}
</blockquote>
<input type="hidden" name="chirpID" value="{{ .ID }}" />
<footer>
<button @fir:like-chirp:ok="$fir.replace()" formaction="?event=like-chirp" type="submit">♥ {{ .LikesCount }}</button>
<button formaction="?event=delete-chirp" type="submit">✕</button>
</footer>
</form>
</section>
5. Error Handling
- Errors are displayed using the
fir.Errortemplate function. - Examples:
- Global errors:
{{ fir.Error "onload" }} - Field-specific errors:
{{ fir.Error "create-chirp.body" }}
- Global errors:
6. Real-Time Updates with WebSocket
- The enhanced version uses WebSocket for real-time updates.
- If WebSocket is disabled, events are sent as HTTP POST requests.
Step 3: Testing the Application
- Open two browser tabs at http://localhost:9867.
- Create a chirp in one tab and see it appear instantly in the other tab.
- Like or delete chirps and observe real-time updates.
Conclusion
Congratulations! You've built a simple real-time Twitter clone using Fir. This example demonstrates how Fir enables progressive enhancement, form validation, and real-time updates with minimal effort. Explore the code further to customize and extend Chirper!
References
Documentation
¶
There is no documentation for this package.