Skip to content

matthewjberger/bamboo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

54 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

bamboo πŸŽ‹

github crates.io license

A fast static site generator written in Rust.

Live Demo Β· cargo install bamboo-cli

Bamboo transforms markdown content with frontmatter into static HTML sites. It features syntax highlighting, Tera templating, live reload development, shortcodes, asset optimization, responsive images, and generates RSS/Atom feeds, sitemaps, and search indexes automatically.

Features

Feature Description
Markdown Full CommonMark support with tables, footnotes, strikethrough, task lists
Frontmatter TOML (+++) or YAML (---) metadata in content files
Syntax Highlighting Built-in highlighting via syntect with configurable themes
Templating Tera templates with inheritance, includes, filters, and macros
Shortcodes Inline ({{</* name */>}}) and block ({{%/* name */%}}) shortcodes with Tera templates
Collections Organize content beyond posts β€” projects, recipes, portfolios (supports nesting)
Data Files Load TOML/YAML/JSON from data/ directory into templates
Pagination Automatic pagination for post listings, tag pages, and category pages
Tags & Categories Auto-generated tag and category index/listing pages
Table of Contents Auto-generated heading-based TOC available in templates
Reading Time Word count and estimated reading time for all content
Search Client-side search with auto-generated JSON index and Fuse.js
Feeds Automatic RSS and Atom feed generation
Sitemap Automatic sitemap.xml generation
Redirects redirect_from frontmatter for old URL redirects
Asset Pipeline CSS/JS/HTML minification and content-hash fingerprinting
Responsive Images Automatic resizing and <picture> srcset generation
Live Reload Development server with automatic rebuild on file changes
Sass/SCSS Automatic Sass/SCSS compilation to CSS
Math LaTeX math rendering with KaTeX support ($...$ inline, $$...$$ display)
Custom Taxonomies Define custom taxonomies beyond tags and categories
Custom Permalinks Override output URL via permalink frontmatter field
Cross-References Link between content with {{</* ref "page.md" */>}} shortcodes
Incremental Builds Only rebuild changed content during development
Themes Built-in default theme with light/dark mode, or use custom themes with overrides

Quick Start

cargo install bamboo-cli
bamboo new my-site
cd my-site
bamboo serve

Open http://localhost:3000 to see your site. Edit files and watch them rebuild instantly.

Template

Use the bamboo-template for a ready-to-deploy starter with GitHub Pages CI included.

CLI Commands

bamboo new <name>              # Create a new site in a new directory
bamboo init                    # Initialize a site in the current directory
bamboo build                   # Build the site to dist/
bamboo build --drafts          # Include draft content
bamboo build --theme ./mytheme # Use a custom theme
bamboo build --output ./public # Custom output directory
bamboo build --base-url <url>  # Override base URL
bamboo serve                   # Dev server with live reload at localhost:3000
bamboo serve --port 8080       # Custom port
bamboo serve --open            # Open browser automatically
bamboo serve --drafts          # Include drafts in dev server

Project Structure

my-site/
β”œβ”€β”€ bamboo.toml              # Site configuration
β”œβ”€β”€ content/
β”‚   β”œβ”€β”€ _index.md            # Home page
β”‚   β”œβ”€β”€ about.md             # Static page β†’ /about/
β”‚   β”œβ”€β”€ docs/                # Nested pages
β”‚   β”‚   └── _index.md        # β†’ /docs/
β”‚   β”œβ”€β”€ posts/               # Blog posts β†’ /posts/<slug>/
β”‚   β”‚   └── 2024-01-15-hello.md
β”‚   └── projects/            # Collection (needs _collection.toml)
β”‚       β”œβ”€β”€ _collection.toml
β”‚       β”œβ”€β”€ my-project.md
β”‚       └── archived/        # Nested subdirectories supported
β”‚           └── old-project.md
β”œβ”€β”€ data/                    # Data files accessible in templates
β”‚   └── nav.toml             # β†’ {{ site.data.nav }}
β”œβ”€β”€ static/                  # Copied as-is to output
β”‚   └── images/
└── templates/               # Site-level template overrides
    └── shortcodes/          # Custom shortcode templates

Configuration

bamboo.toml:

title = "My Site"
base_url = "https://example.com"
description = "A site built with Bamboo"
author = "Your Name"
language = "en"
posts_per_page = 10    # Posts per page (0 = all on one page)
syntax_theme = "base16-ocean.dark"  # Syntax highlighting theme
math = false           # Enable LaTeX math rendering
minify = false         # Minify CSS, JS, and HTML output
fingerprint = false    # Content-hash asset filenames for cache busting

[taxonomies.tags]      # Built-in (auto-configured)
singular = "tag"

[taxonomies.categories]  # Built-in (auto-configured)
singular = "category"

[images]               # Responsive image generation (optional)
widths = [320, 640, 1024, 1920]
quality = 80
formats = ["webp", "jpg"]

[extra]
github = "https://github.com/username"

All [extra] fields are available in templates as {{ site.config.extra.github }}.

Content

Frontmatter

TOML style:

+++
title = "My Post"
date = "2024-01-15"
tags = ["rust", "web"]
categories = ["tutorials"]
draft = false
weight = 10
template = "custom.html"
excerpt = "Custom excerpt text"
redirect_from = ["/old-url/"]
+++

Your content here...

YAML style:

---
title: My Post
date: 2024-01-15
tags:
  - rust
  - web
---

Your content here...

Frontmatter Fields

Field Type Applies to Description
title string all Page/post title (defaults to filename)
date date posts Publication date (or parsed from filename)
draft bool all Exclude from build unless --drafts flag
tags array posts Post tags for tag pages
categories array posts Post categories for category pages
weight number pages, items Sort order (lower = first)
template string all Override default template
excerpt string posts Custom excerpt (auto-generated from first paragraph if omitted)
permalink string all Override the output URL (e.g. /custom-path/)
redirect_from array posts, pages Old URLs that redirect to this content
math bool all Enable LaTeX math for this page (when not globally enabled)

Date from Filename

Posts can embed dates in filenames: 2024-01-15-hello-world.md extracts date 2024-01-15 and slug hello-world.

Nested Pages

Pages can be organized in subdirectories. Use _index.md for directory index pages:

  • content/docs/_index.md β†’ /docs/
  • content/docs/getting-started.md β†’ /docs/getting-started/

Shortcodes

Shortcodes embed reusable components in markdown content.

Inline Shortcodes

{{</* youtube id="dQw4w9WgXcQ" */>}}
{{</* figure src="/images/photo.jpg" caption="A photo" */>}}
{{</* gist user="username" id="abc123" */>}}

Block Shortcodes

Block shortcodes wrap markdown content:

{{%/* note type="warning" title="Heads up" */%}}
This content is rendered as **markdown** inside the shortcode.
{{%/* /note */%}}

{{%/* details summary="Click to expand" */%}}
Hidden content here.
{{%/* /details */%}}

Built-in Shortcodes

Shortcode Type Parameters
youtube inline id (required), title
figure inline src (required), alt, caption, width, height, class
gist inline user (required), id (required), file
note block type (info/warning/error), title, body content
details block summary, open, body content

Custom Shortcodes

Place Tera HTML templates in templates/shortcodes/. Parameters become template variables:

<!-- templates/shortcodes/alert.html -->
<div class="alert alert-{{ level }}">{{ body }}</div>
{{%/* alert level="danger" */%}}
Something went wrong!
{{%/* /alert */%}}

Templating

Bamboo uses Tera for templating. Templates live in your theme's templates/ directory. Site-level templates in templates/ override theme templates.

Template Context

All templates receive:

Variable Description
site.config bamboo.toml contents
site.config.title Site title
site.config.base_url Base URL
site.config.extra.* Custom fields from [extra]
site.pages All pages (for navigation)
site.data Data from data/ directory
site.collections Map of collection name to collection

Index template (index.html):

Variable Description
posts Posts for current page (first posts_per_page)
home / page Home page content (from _index.md)
current_page Current page number
total_pages Total number of pages
next_page_url URL to next page (if exists)

Post template (post.html):

Variable Description
post.title Post title
post.content Rendered HTML (use {{ post.content | safe }})
post.date Publication date
post.tags Tag list
post.categories Category list
post.excerpt Auto-generated or custom excerpt
post.slug URL slug
post.url Full URL path
post.word_count Word count
post.reading_time Estimated minutes to read
post.toc Table of contents entries
prev_post Previous (older) post
next_post Next (newer) post

Page template (page.html):

Variable Description
page.title Page title
page.content Rendered HTML
page.slug URL slug
page.url Full URL path
page.word_count Word count
page.reading_time Estimated minutes to read
page.toc Table of contents entries

Tag/Category page templates (tag.html, category.html):

Variable Description
tag_name / category_name Display name
tag_slug / category_slug URL slug
posts Posts with this tag/category (paginated)
current_page, total_pages Pagination info
prev_page_url, next_page_url Pagination links

Collection templates (collection.html, collection_item.html):

Variable Description
collection Collection with name and items
collection_name Collection name
item Current item (in item template)

Custom Filters

Filter Description
slugify Convert text to URL slug
reading_time Estimated minutes to read content
word_count Count words in content
toc Render table of contents as HTML (use with | safe)

Template Example

{% extends "base.html" %}

{% block content %}
<article>
  <h1>{{ post.title }}</h1>
  <time>{{ post.date | date(format="%B %d, %Y") }}</time>
  <span>{{ post.reading_time }} min read</span>

  <div class="tags">
    {% for tag in post.tags %}
    <a href="{{ site.config.base_url }}/tags/{{ tag | slugify }}/">{{ tag }}</a>
    {% endfor %}
  </div>

  {{ post.content | safe }}
</article>
{% endblock %}

Data Files

Place TOML, YAML, or JSON files in data/. They're accessible as site.data.<filename>.

# data/social.toml
[[links]]
name = "GitHub"
url = "https://github.com/username"

[[links]]
name = "Twitter"
url = "https://twitter.com/username"
<!-- In template -->
{% for link in site.data.social.links %}
<a href="{{ link.url }}">{{ link.name }}</a>
{% endfor %}

Nested directories work: data/nav/main.toml β†’ site.data.nav.main

Themes

Bamboo includes a built-in default theme with light/dark mode toggle. Create custom themes by specifying a theme directory:

bamboo build --theme ./my-theme

Theme Structure

my-theme/
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ base.html
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ page.html
β”‚   β”œβ”€β”€ post.html
β”‚   β”œβ”€β”€ collection.html
β”‚   β”œβ”€β”€ collection_item.html
β”‚   β”œβ”€β”€ tags.html
β”‚   β”œβ”€β”€ tag.html
β”‚   β”œβ”€β”€ categories.html
β”‚   β”œβ”€β”€ category.html
β”‚   β”œβ”€β”€ pagination.html
β”‚   β”œβ”€β”€ search.html
β”‚   β”œβ”€β”€ 404.html
β”‚   β”œβ”€β”€ shortcodes/
β”‚   β”‚   └── *.html
β”‚   └── partials/
β”‚       β”œβ”€β”€ header.html
β”‚       β”œβ”€β”€ footer.html
β”‚       └── nav.html
└── static/
    └── css/

Theme Overrides

Override specific templates without creating a full theme by placing templates in your site's templates/ directory. These take priority over theme templates.

Examples

The repository includes example sites:

Example Description Command
blog Standard blog with posts, pages, collections just example blog
book Book with chapters, sidebar navigation, prev/next just example book
changelog Software release notes and changelog just example changelog
docs Documentation site with sidebar navigation just example docs
landing Product landing page with pricing just example landing
portfolio Creative portfolio with project showcase just example portfolio
slideshow Presentation/slideshow site just example slideshow

Output

Building generates:

dist/
β”œβ”€β”€ index.html               # Home page
β”œβ”€β”€ style.css                 # Theme stylesheet (built-in theme)
β”œβ”€β”€ 404.html                  # Not found page
β”œβ”€β”€ about/index.html          # Static pages
β”œβ”€β”€ posts/
β”‚   └── hello/index.html      # Blog posts
β”œβ”€β”€ tags/
β”‚   β”œβ”€β”€ index.html            # Tags listing
β”‚   └── rust/index.html       # Per-tag post listing
β”œβ”€β”€ categories/
β”‚   β”œβ”€β”€ index.html            # Categories listing
β”‚   └── tutorials/index.html  # Per-category post listing
β”œβ”€β”€ page/
β”‚   └── 2/index.html          # Pagination pages
β”œβ”€β”€ search/
β”‚   └── index.html            # Search page
β”œβ”€β”€ projects/
β”‚   β”œβ”€β”€ index.html            # Collection index
β”‚   β”œβ”€β”€ my-project/index.html # Collection items
β”‚   └── archived/
β”‚       └── old-project/index.html  # Nested collection items
β”œβ”€β”€ rss.xml                   # RSS feed
β”œβ”€β”€ atom.xml                  # Atom feed
β”œβ”€β”€ sitemap.xml               # Sitemap
└── search-index.json         # Client-side search index

As a Library

Use bamboo-ssg as a library in your own tools:

[dependencies]
bamboo-ssg = "0.2.5"
use bamboo_ssg::{SiteBuilder, ThemeEngine};

let mut builder = SiteBuilder::new("./my-site")
    .base_url("https://example.com")
    .include_drafts(false);

let site = builder.build()?;

let theme = ThemeEngine::new("default")?;
theme.render_site(&site, "./dist")?;

License

Dual-licensed under MIT (LICENSE-MIT) or Apache 2.0 (LICENSE-APACHE).

About

A fast static site generator, written in rust πŸ¦€

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Contributors