Build static websites from the command line — site structure, YAML content, themes, and deployment.
secms (Simply Efficient CMS) is a fast static site generator. It takes your content (written in simple YAML files) and a theme, and produces a complete website — HTML, CSS, JavaScript, and images — ready to upload to any web host.
If you use the seCMS GUI desktop app, the GUI handles running secms for you automatically. This manual covers using secms directly from the command line, which is useful for automation, scripting, or advanced workflows.
Your Content (YAML files) + Theme (templates + styles) → Website (HTML/CSS/JS)
Benefits:
Download the secms binary for your platform and place it somewhere in your PATH.
If you have Go installed:
cd secms/
go build -o bin/secms ./cmd/secms/
This produces the bin/secms binary.
secms --help
Here's how to build a site in under 2 minutes:
mkdir my-site
cd my-site
name: My Website
base_url: https://example.com
description: A simple website
theme: starter
menu:
- label: Home
path: /
- label: About
path: /about
pages:
- index
- about
Create a content/ directory and add your pages:
content/index.yaml:
id: index
title: Home
path: /
description: Welcome to my website
sections:
- id: welcome
title: Welcome
content: |
<p>Hello! This is my website. I'm glad you're here.</p>
- id: about-me
title: About Me
content: |
<p>I'm a web designer based in Seoul. I love creating
beautiful, functional websites.</p>
content/about.yaml:
id: about
title: About
path: /about
description: Learn more about us
sections:
- id: story
title: Our Story
content: |
<p>We started this company in 2020 with a simple mission:
make the web a more beautiful place.</p>
secms --site . --themes /path/to/themes
secms --site . --themes /path/to/themes --serve
Open http://localhost:8080 in your browser.
When you run secms, it performs these steps:
site.yaml) to understand the site structure, menu, and theme choice.content/*.yaml files.The result is a dist/ folder containing your complete website.
A site directory looks like this:
The site.yaml file is the heart of your site. It defines everything about your website.
name: My Website
base_url: https://example.com
description: A brief description of your website
theme: starter
copyright: "© 2026 My Website. All rights reserved."
| Field | Required | Description |
|---|---|---|
name | Yes | Your website's name |
base_url | Yes | The full URL where your site will be hosted |
description | Yes | A short description (used in search results) |
theme | Yes | Name of the theme to use |
copyright | No | Copyright notice shown in the footer |
menu:
- label: Home
path: /
- label: About
path: /about
- label: Services
path: /services
children:
- label: Web Design
path: /services/design
- label: Branding
path: /services/branding
- label: Blog
url: https://blog.example.com
external: true
pages:
- index
- about
- contact
- services
- services/design
- services/branding
This lists the page IDs (matching filenames in content/). The order determines the build order.
meta:
author: Your Name
lang: en
charset: utf-8
viewport: width=device-width, initial-scale=1.0
# Generate a sitemap.xml and robots.txt
sitemap:
enabled: true
changefreq: weekly
# Generate an RSS/Atom feed
feed:
enabled: true
title: My Blog Feed
path: /feed.xml
limit: 20
# Add analytics or custom scripts to the page head
head_scripts:
- src: "https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"
async: true
- inline: |
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
Each page is a YAML file in the content/ directory.
id: about
title: About Us
path: /about
description: Learn about our company and team
sections:
- id: intro
title: Who We Are
content: |
<p>We are a team of passionate creators.</p>
| Field | Description |
|---|---|
id | Unique identifier (must match the filename without .yaml) |
title | Page title (shown in browser tab and on the page) |
path | URL path (e.g., /about, /services/design) |
| Field | Description |
|---|---|
description | SEO description (shown in search results) |
banner | Path to a banner image (e.g., /images/banner.jpg) |
file | Output filename override (default: index.html) |
sections | List of content sections (see below) |
You can organize pages in subdirectories:
In site.yaml, list these with their full path:
pages:
- services
- services/design
- services/branding
Content is written inside sections. Each section has a title, content (HTML), and optional styling.
sections:
- id: welcome
title: Welcome
content: |
<p>This is a paragraph of text.</p>
<p>This is another paragraph with <strong>bold</strong>
and <em>italic</em> text.</p>
📚 Note: The
|aftercontent:means "multi-line text". Indent the content with spaces.
| Element | Example | Result |
|---|---|---|
| Paragraph | <p>Text here</p> | A paragraph of text |
| Bold | <strong>bold</strong> | bold |
| Italic | <em>italic</em> | italic |
| Link | <a href="/about">About</a> | A clickable link |
| Image | <img src="/images/pic.jpg"> | An image |
| Heading | <h2>Subtitle</h2> | A sub-heading |
| List | <ul><li>Item</li></ul> | A bullet list |
| Numbered | <ol><li>First</li></ol> | A numbered list |
content: |
<img src="/images/team.jpg" class="float-left" alt="Our team">
<p>Meet our amazing team of designers and developers who
bring your ideas to life.</p>
Image positioning classes:
float-left — Image on the left, text wraps around itfloat-right — Image on the right, text wraps around itcenter — Image centeredfull-width — Image stretches to full widthIf you have text that appears on multiple pages (like a disclaimer or footer note), put it in the includes/ directory:
# includes/disclaimer.md
**Disclaimer:** The information on this website is for general
informational purposes only.
Then reference it in your page:
sections:
- id: disclaimer
title: ""
content: !include includes/disclaimer.md
Files ending in .md are automatically converted from Markdown to HTML.
The menu is defined in site.yaml. It controls the navigation bar on your website.
menu:
- label: Home
path: /
- label: About
path: /about
- label: Contact
path: /contact
menu:
- label: Home
path: /
- label: Services
path: /services
children:
- label: Web Design
path: /services/design
- label: Branding
path: /services/branding
- label: Marketing
path: /services/marketing
- label: Contact
path: /contact
menu:
- label: Home
path: /
- label: Our Blog
url: https://blog.example.com
external: true
Setting external: true makes the link open in a new browser tab.
| Field | Description |
|---|---|
label | The text shown in the navigation (required) |
path | Internal page path (e.g., /about) |
url | External URL (use instead of path for outside links) |
external | true to open in a new tab |
children | Sub-menu items (creates a dropdown) |
class | CSS class for custom styling (e.g., cta-button) |
Themes control the visual appearance of your site. secms comes with several built-in themes.
| Theme | Description |
|---|---|
starter | Clean, minimal starting point |
blueprint | Professional business design |
bizcraft | Corporate and business |
boutique | Creative portfolio and shop |
cineplex | Entertainment and media |
docpress | Documentation and knowledge base |
flavor | Restaurant and food business |
photofocus | Photography portfolio |
runable | Modern app and startup |
techcatalog | Technology product showcase |
Change the theme field in your site.yaml:
theme: blueprint
Then rebuild your site. Your content stays the same — only the design changes.
Place your images and other static files in the static/ directory of your site:
In your content, reference static files with a leading /:
<img src="/images/logo.png" alt="Logo">
<img src="/images/team/alice.jpg" alt="Alice">
If your site has a file with the same path as a theme file, your site's version wins. This lets you customize theme assets without modifying the theme itself.
secms --site /path/to/my-site --themes /path/to/themes
This generates your website in my-site/dist/.
secms --site /path/to/my-site --themes /path/to/themes --serve
Opens a local server at http://localhost:8080 so you can preview the result in your browser.
secms --site /path/to/my-site --themes /path/to/themes --out /path/to/output
| Flag | Default | Description |
|---|---|---|
--site | (required) | Path to your site directory |
--themes | themes/ | Path to the themes directory |
--out | {site}/dist/ | Output directory |
--clean | true | Remove output directory before building |
--serve | false | Start local preview server after building |
--port | 8080 | Port for the preview server |
After building, the dist/ folder contains your complete website. Upload it to any web host:
dist/ folder, or connect to Git for automatic deploys.dist/ contents to a gh-pages branch.dist/.dist/ contents to an S3 bucket configured for static hosting.dist/ folder directly.Upload the contents of dist/ to your web server's public directory (often public_html/ or www/) using FTP or your hosting provider's file manager.
Since secms is a single command, you can easily add it to CI/CD pipelines:
# Example: build and deploy to Netlify
secms --site . --themes themes/
netlify deploy --dir dist/
secms includes a tool to convert Jekyll themes into secms-compatible themes. This is useful if you find a Jekyll theme you like and want to use it with secms.
secms-tmplt-convert /path/to/jekyll-theme.zip /path/to/output-theme
| Flag | Description |
|---|---|
--verbose | Show detailed conversion progress |
--skip-scss | Skip SCSS compilation (copy raw files instead) |
theme.yaml configurationDart Sass (optional, for SCSS compilation): Install with npm install -g sass
The converted theme may need minor manual adjustments. Check the generated README.md in the output directory for details on what was converted and what may need attention.
secms [flags]
Flags:
--site string Path to site directory (required)
--themes string Path to themes directory (default "themes/")
--out string Output directory (default "{site}/dist/")
--clean Remove output dir before building (default true)
--serve Start local server after building (default false)
--port int Server port (default 8080)
These functions are available in theme templates. You generally don't need to know these unless you're customizing a theme.
| Function | Description | Example |
|---|---|---|
safeHTML | Output raw HTML | {{safeHTML .Content}} |
markdown | Convert Markdown to HTML | {{markdown .Text}} |
upper | Uppercase text | {{upper "hello"}} → HELLO |
lower | Lowercase text | {{lower "HELLO"}} → hello |
truncate | Shorten text | {{truncate 100 .Description}} |
year | Current year | {{year}} → 2026 |
default | Fallback value | {{default "N/A" .Value}} |
slugify | URL-safe string | {{slugify "Hello World"}} → hello-world |
dict | Create a data map | {{dict "key" "value"}} |
add | Add numbers | {{add 1 2}} → 3 |
contains | Check if contains | {{contains .List "item"}} |
Each section in a page's sections list supports these fields:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique section identifier |
title | No | Section heading |
content | No | HTML content (use | for multi-line) |
widget | No | Interactive component name (e.g., contact-form) |
style | No | CSS for the section container |
content_style | No | CSS for the inner content |
align | No | Text alignment: left, center, right |
border | No | CSS border (e.g., 2px solid #ccc) |
animation.effect | No | Animation type: sun, moon, rain, snow, etc. |
animation.image | No | Image for the animation |
animation.speed | No | Speed 1-10 (default 5) |
animation.direction | No | left or right |
extra | No | Custom key-value data for themes |