Lichen

Lichen

Lichen is the simplest possible CMS for the web that is friendly enough for non-technical users. It is extremely lightweight.

To get started, download Lichen, unzip it, and upload the contents to your web host's public directory. Follow the setups below.

Download Setup Steps

See sites made with Lichen and share your own on the Lichen Webring.

Lichen Webring

Usage

Demo

Logging In

Once you've completed the setup steps and Lichen is running on your web server, navigate your browser to:

/cms/edit.php

Rationale

Many people reach for WordPress or something similar, which is overkill in many cases. Plugins, security updates, and a SQL database are a lot of overhead for sharing text and images online. On the other hand, writing HTML and CSS by hand is so complex these days that the layperson has no time or interest to learn to do it, not to mention understanding what a SSH key is and how to edit the site over SFTP. Installing dependencies, compiling a static site, and managing a Git repo involves similar complexity.

Lichen is designed to hit the sweet spot between WordPress and manually editing HTML. A technically-inclined person can easily set up many Lichen sites for friends with minimal effort and maintenance (it's only 3 PHP files) without having to worry about the technical burden of maintaining a database-driven CMS.

Content is stored as Gemtext, the lightweight markup language of the Gemini protocol. Why Gemtext?

  1. It's easier to learn and more forgiving than Markdown.
  2. You don't need a heavy JavaScript-enabled rich-text WYSIWYG editor.
  3. It's simple to parse and render (no Markdown library necessary).
  4. Constraints breed creativity.
  5. As an added bonus, content authored in Gemtext is automatically Gemini-friendly.
Gemtext Introduction

The content is the most important part of a site. When your content is constrained to a single column of text with hand-edited links, it is more intimate and intentional. The writer is required to make the content good enough to be worth reading without relying on the crutch of complex layouts and fancy web widgets everywhere. The reader is no longer burdened with heavy web pages and distracting/buggy UI. All of this adds up to an extremely lightweight environment: low cost, low resources, low cognitive overhead, low environmental impact.

Hosting Requirements

The only hosting requirement is a bog-standard Apache web host that supports PHP 7. libgd must be installed for image resizing.

We prefer NearlyFreeSpeech. Their prices are pay-for-what-you-use (very low), and you can very easily setup many domains on a single low-cost server.

NearlyFreeSpeech.net

Setup

  1. Copy everything in this directory to your server's public directory.
  2. Modify 'theme/layout.php' to your liking. Upload any additional assets you may need, like stylesheets.
  3. 🚨 Important! 🚨 Create a htpasswd file and set its path in the 'cms/.htaccess' file.
htpasswd Documentation

Directory Structure

.
β”œβ”€β”€ cms
β”‚   β”œβ”€β”€ edit.php
β”‚   β”œβ”€β”€ gemtext.php
β”‚   └── render.php
β”œβ”€β”€ theme
β”‚   └── layout.php
β”œβ”€β”€ .htaccess
β”œβ”€β”€ index.gmi
└── assets
	β”œβ”€β”€ image.jpg
	└── stylesheet.css
  1. 'cms' contains the Lichen code
  2. 'theme' contains the layout templates (not publicly accessible)
  3. '.htaccess' configures Apache to render Gemtext files as HTML and configures access control
  4. Everything else is free-form static hosting

Nginx

If you'd like to use Nginx instead of Apache, delete all of the .htaccess files and use this configuration:

map $is_redirected $auth_type {
	default "Restricted";
	true "off";
}

server {
	listen 80;
	root /var/www/html;

	include mime.types;
	index index.gmi;

	location / {
		# --- discard .gmi extensions and redirect
		rewrite (.*)\.gmi$ $1 permanent;

		# --- try .gmi files without extensions
		if (-f ${document_root}${uri}.gmi) {
			set $redirect_url ${uri}.gmi;
			set $is_redirected true;
			rewrite ^(.*)$ /cms/render.php?${redirect_url} last;
		}
		# --- try index files
		if (-f ${document_root}${uri}index.gmi) {
			set $redirect_url ${uri}index.gmi;
			set $is_redirected true;
			rewrite ^(.*)$ /cms/render.php?${redirect_url} last;
		}
		try_files $uri $uri/ =404;
	}

	location /cms/ {
		auth_basic $auth_type;
		auth_basic_user_file /home/private/lichen.htpasswd;

		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		set $path_info $fastcgi_path_info;

		fastcgi_pass unix:/run/php/php-fpm.sock;
		include fastcgi_params;


		fastcgi_param REDIRECT_URL $redirect_url if_not_empty;
		fastcgi_param SCRIPT_FILENAME ${document_root}${fastcgi_script_name};
		fastcgi_param PATH_INFO $path_info;

		try_files $fastcgi_script_name =404;
	}

	location /theme/ {
		return 404;
	}
}

Layout

The main HTML template is 'theme/layout.php'. This template is rendered with the content of the current Gemtext file. The following PHP variables are provided:

  1. $path: the absolute path of the Gemtext file being requested (e.g. '/index.gmi')
  2. $title: the content of the first heading, useful for placing in the HTML <title> tag
  3. $body: the content of the Gemtext rendered to HTML

Image Processing

Not everyone is familiar with appropriate resolutions and image optimization for the web, so PHP's GD can be used to automatically resize uploaded images. The original source image will be discarded when this is enabled. Use the following environment variables:

  1. IMG_RESIZE_ENABLE: 'true' to enable (disabled by default)
  2. IMG_RESIZE_FORMAT: 'source' to use the same format as the original, or force everything to 'jpeg', 'gif', 'png', 'bmp', 'webp', or 'avif' (default 'source')
  3. IMG_RESIZE_MAX_WIDTH: number in pixels, images larger than this width will be reduced (default 800)
  4. IMG_RESIZE_JPEG_QUALITY: quality from 0 to 100 (library default is ~75)
  5. IMG_RESIZE_PNG_COMPRESSION: compression level from 0 to 9
  6. IMG_RESIZE_AVIF_QUALITY: quality from 0 to 100 (library default is 30)
  7. IMG_RESIZE_AVIF_SPEED: speed from 0 (slow, smaller file) to 10 (fast, larger file) (library default is 6)
  8. IMG_RESIZE_WEBP_QUALITY: quality from 0 to 100

These environment variables can be set in .htaccess if Apache's mod_env is enabled. See the provided .htaccess file.

Note that filenames must not have spaces in order to be compatible with the Gemtext link format. To facilitate this, spaces in filenames are automatically replaced with underscores when uploading via the editor UI.

Changelog

2022-05-20

  1. Documented sample nginx configuration (@flyingrub@merveilles.town)

2022-05-15

  1. Editor textarea forced to monospace typeface
  2. Better checking to ignore CMS directories
  3. Fixed syntax error (@milofultz@merveilles.town)
  4. Headers are limited to level 3 (@aw@merveilles.town)
  5. List items require space between asterisk and content (@aw@merveilles.town)
  6. No whitespace is tolerated before directives (@aw@merveilles.town)
  7. Nested directives are no longer allowed (@aw@merveilles.town)
  8. Alt tags are supported for preformatted blocks (@aw@merveilles.town)
  9. Blockquotes are limited to single line (@aw@merveilles.town)
  10. Ability to create new directories
  11. Ability to delete directories
  12. Empty directories are now displayed
  13. Improved file manager iconography

2022-05-10

  1. Case-insensitive file extension handling
  2. PHP7 support (@scops@social.tchncs.de)

2022-05-09

Initial release.

License

The MIT License (MIT)

Copyright Β© 2022 Sensor Station LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the β€œSoftware”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED β€œAS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.