Quick Start Guide
Before starting, make sure you have installed Hologram correctly by following the Installation Guide.
Let's build a simple blog application to demonstrate Hologram's key features. Our blog will have:
- A home page listing blog posts
- Individual post pages
- A layout with navigation
- The ability to like posts
Creating the Layout
First, let's create a layout that will be shared across all pages:
defmodule Blog.MainLayout do
use Hologram.Component
alias Hologram.UI.Link
alias Hologram.UI.Runtime
def template do
~H"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Blog</title>
<Runtime />
</head>
<body>
<nav>
<Link to={Blog.HomePage}>Home</Link>
</nav>
<main>
<slot />
</main>
</body>
</html>
"""
end
end
Creating the Home Page
Now let's create the home page that lists blog posts:
defmodule Blog.HomePage do
use Hologram.Page
alias Blog.Components.PostPreview
route "/"
layout Blog.MainLayout
def init(_params, component, _server) do
posts = [
%{id: 1, title: "First Post", excerpt: "This is my first post"},
%{id: 2, title: "Second Post", excerpt: "Another great post"}
]
put_state(component, :posts, posts)
end
def template do
~H"""
<h1>Welcome to my Blog</h1>
<div class="posts">
{%for post <- @posts}
<PostPreview post={post} />
{/for}
</div>
"""
end
end
Creating a Post Preview Component
Let's create a reusable component for displaying post previews:
defmodule Blog.Components.PostPreview do
use Hologram.Component
alias Hologram.UI.Link
prop :post, :map
def template do
~H"""
<article class="post-preview">
<h2>{@post.title}</h2>
<p>{@post.excerpt}</p>
<Link to={Blog.PostPage, id: @post.id}>Read more</Link>
</article>
"""
end
end
Creating the Post Page
Now let's create a page for individual posts with a like button:
defmodule Blog.PostPage do
use Hologram.Page
route "/posts/:id"
param :id, :integer
layout Blog.MainLayout
def init(params, component, _server) do
# In real app, fetch from database
post = %{
id: params.id,
title: "Example Post",
content: "This is the full content...",
likes: 0
}
put_state(component, :post, post)
end
def template do
~H"""
<article>
<h1>{@post.title}</h1>
<p>{@post.content}</p>
<div class="likes">
Likes: {@post.likes}
<button $click="like_post">Like</button>
</div>
</article>
"""
end
def action(:like_post, _params, component) do
# Update likes locally first for instant feedback
put_state(component, :post, %{
component.state.post |
likes: component.state.post.likes + 1
})
|> put_command(:save_like, post_id: component.state.post.id)
end
def command(:save_like, params, server) do
# In real app, save to database
IO.puts("Liked post #{params.post_id}")
server
end
end
Key Concepts Demonstrated
- Pages: both
HomePage
andPostPage
are Hologram pages with their own routes - Components: the
PostPreview
component shows how to create reusable UI elements - Layout: the
MainLayout
provides a consistent structure across pages - Template Syntax:
- Using
{%for}
loops - Interpolating values with
{@var}
- Event binding with
$click
- Using
- Navigation: using
Link
component to navigate between pages - State Management: using
put_state/3
to manage component state - Actions & Commands: the like button demonstrates:
- Client-side action for immediate UI update
- Server-side command for persistence
- Props: component properties with the
prop/2
macro - Parameters: route parameters with the
param/2
macro
This example demonstrates the basic building blocks of a Hologram application. The framework handles the client-server communication and state management automatically, letting you focus on building features.
Remember that Hologram keeps state on the client side for better performance while using commands for server-side operations when needed.