
Security News
CISA’s 2025 SBOM Guidance Adds Hashes, Licenses, Tool Metadata, and Context
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Scriptorium is a major refactoring (rewrite) of Runeblog, which had an unwieldy and fragile code base. The plan now is to develop with more of a test-first approach (and with AI support from ChatGPT and Gemini).
Scriptorium is a static site generator designed for creating and managing multiple blogs or content sites from a single installation. It combines the simplicity of static file generation with the power of a multi-view architecture, allowing you to maintain several distinct websites with shared infrastructure.
Scriptorium generates static HTML, CSS, and JavaScript files. This approach offers several key benefits:
When you publish content with Scriptorium, it generates a complete set of static files that can be deployed to any web hosting service - from simple file hosting to sophisticated CDN networks.
Scriptorium's most distinctive feature is its multi-view architecture. Instead of managing separate installations for different blogs or websites, you can create multiple "views" within a single Scriptorium repository.
What is a view? A view represents a complete, independent website or blog. Each view has its own:
Why use views?
For example, you might have:
All managed from the same Scriptorium installation, with shared themes and infrastructure but completely independent content.
A Scriptorium repository is a directory that contains everything needed to manage your views and generate your websites. The repository structure follows a logical organization:
scriptorium/
├── config/ # Global configuration files
├── views/ # Individual view directories
│ ├── personal/ # Personal blog view
│ ├── portfolio/ # Professional portfolio view
│ └── docs/ # Documentation view
├── drafts/ # Draft posts (global)
├── posts/ # Generated posts (global)
├── assets/ # Shared images and files
├── themes/ # Theme templates
└── scripts/ # Utility scripts
Key Repository Concepts:
Scriptorium generates static files that can be deployed to virtually any web hosting service. The deployment process is straightforward:
Deployment options include:
The static nature of Scriptorium's output means you have maximum flexibility in choosing where and how to host your content. [Detailed deployment instructions are covered in Section 9.]
LiveText is a templating and content processing system that powers Scriptorium's content generation. It provides a simple, powerful way to create dynamic content while maintaining the benefits of static file generation.
Scriptorium could have used any number of templating systems (Markdown, Liquid, ERB, etc.), but LiveText was chosen for several key reasons:
LiveText bridges the gap between static content and dynamic generation, allowing you to create sophisticated websites while maintaining the performance and reliability benefits of static files.
LiveText uses a simple but powerful syntax based on "dot commands" and inline formatting. Here's a quick overview:
Inline formatting:
This is *bold and this is _italic text.
This is *[multiple words boldfaced].
Dot commands with parameters:
.title My Blog Post
.date 2025-07-29
.tags ruby, programming, blog
.link https://example.com Visit Example
.image /images/photo.jpg My Photo
Dot commands with body content:
.quote
This is an inset quote.
Wherever you go,
there you are.
.end
Variables and functions:
This file is called $File (predefined var).
The current time is: $$time
This post has $$word_count words.
LiveText's syntax is designed to be readable and writable, making it easy to create content without getting bogged down in complex templating syntax. [Complete LiveText documentation is provided in Section 3.]
Scriptorium is distributed as a Ruby gem, making installation straightforward:
gem install scriptorium
Prerequisites:
After installation, you'll have access to the scriptorium
command-line tool, which provides an interactive interface for managing your blogs and content.
The easiest way to get started with Scriptorium is through the interactive setup process. Simply run:
scriptorium
This launches the interactive Scriptorium tool, which will guide you through the initial setup.
When you first run Scriptorium, it will detect that no repository exists and offer to create one:
No repository found.
Create new repository? (y/n): y
The repository will be created in your home directory as ~/.scriptorium
by default. This directory will contain all your views, posts, themes, and configuration.
After creating the repository, Scriptorium will offer to help you create your first view:
Do you want assistance in creating your first view? (y/n): y
A view represents a complete website or blog. You'll be prompted for:
For example:
View name: personal
View title: My Personal Blog
View subtitle: Thoughts on programming and life
Scriptorium automatically creates a sample view to help you get started. This view includes:
You can explore the sample view to understand how Scriptorium works, then customize it or create new views for your specific needs.
Once your repository is set up, you can use these basic commands in the Scriptorium shell:
View management:
view # Show current view
list views # List all views
change view <name> # Switch to a different view
new view <name> <title> # Create a new view
Content management:
list posts # List posts in current view
list drafts # List draft posts
new post <title> # Create a new post
Generation and deployment:
generate # Regenerate current view
preview # Preview current view locally
deploy # Deploy current view to server
Help and information:
help # Show available commands
version # Show Scriptorium version
quit # Exit Scriptorium shell
Scriptorium uses your preferred text editor for creating and editing content. For simplicity and lack of distraction, something like vim or emacs is recommended. (The ancient editor ed is mentioned here partly as a joke; but in fact, Scriptorium does use ed in automated testing.)
On first use, you'll be prompted to choose an editor:
Available editors:
1. nano
2. vim
3. emacs
4. ed
Choose editor (1-4): 1
Your choice is saved in config/editor.txt
and will be used for all future editing sessions.
Recommended editors:
Each view has its own configuration file at views/<viewname>/config.txt
. This file contains basic settings:
title My Personal Blog
subtitle Thoughts on programming and life
theme standard
Key configuration options:
Global settings are stored in the config/
directory:
Typically you would not change any of these manually. The last two especially are managed internally by Scriptorium.
Scriptorium includes a comprehensive dependency checker to ensure all required tools are available:
ruby scripts/check_dependencies.rb
This will check for:
The checker provides specific installation instructions for any missing dependencies.
Example output:
🔍 Scriptorium Dependency Checker
==================================================
📊 Dependency Status
==================================================
Individual Dependencies:
------------------------------
Ruby ✅ Available
Python 3 ✅ Available
Redd gem (Reddit API) ❌ Missing
LiveText ✅ Available
ImageMagick ✅ Available
Feature Availability:
------------------------------
Core Blogging ✅ Ready
Reddit Button ✅ Ready
Reddit Autopost ❌ Missing Dependencies
Missing: redd
Scriptorium comes with a single theme called "standard" that provides a clean, responsive design suitable for most blogs and websites.
The standard theme includes:
Any future (or cloned) theme will have essentially the same structure. The standard theme is located in themes/standard/
and includes:
themes/standard/
├── templates/ # LiveText templates
│ ├── post.lt3 # Individual post template
│ ├── index.lt3 # Front page template
│ └── widget.lt3 # Widget template
├── layout/ # Layout configuration
│ ├── layout.txt # Layout definition
│ ├── config/ # Layout components
│ └── gen/ # Generated CSS/HTML
└── assets/ # Theme assets (images, etc.)
You can customize the standard theme by:
clone standard mytheme
(creates a copy to modify)templates/
layout/
Predefined themes are considered immutable. Of course, there is only one at this point. Later on, there should be a distinction between predefined and user-defined (or cloned) themes.
[Detailed theme customization is covered in Section 7.]
**[TO BE DONE]
The front page of your Scriptorium view is built using a container-based layout system. Each container serves a specific purpose and can be configured independently:
Front page containers:
+------------------------------------------+
| Header |
| (banner, title, subtitle, navigation) |
+------------------------------------------+
| | | |
| Left | Main | Right |
| Sidebar| (post index) | Sidebar |
| | | |
+------------------------------------------+
| Footer |
+------------------------------------------+
The header configuration is defined in views/<viewname>/config/header.txt
. The header can include:
# Header configuration example
title
subtitle
banner svg
nav
Header components:
navbar.txt
Navigation is configured in views/<viewname>/config/navbar.txt
using a simple syntax:
=About
Vision & Mission mission
Board of Directors board
Partners partners
How You Can Help howtohelp
-Social Media socmed
=Resources
Space links links
Space on Twitter twitter
Space on Instagram instagram
Space Newsfeeds rssnews
-Companion sites oursites
-Blog embed-blog
-Contact contact
Navigation syntax:
The navigation generates a Bootstrap navbar with responsive design.
Sidebars are optional containers that can appear on the left or right side of your main content. They're perfect for widgets and additional information.
Sidebar configuration: Sidebars are configured through the layout system and can contain widgets. The layout determines whether sidebars appear and on which side.
The main container is where your primary content appears. On the front page, this typically shows a listing of your blog posts:
Post listing features:
Widgets are reusable content components that can be placed in sidebars. Scriptorium includes several built-in widgets:
The Links widget displays a list of external links. Configuration is in config/widgets.txt
:
links
Links widget data:
Links are defined in config/links.txt
with one link per line:
https://ruby-lang.org, Ruby Language
https://github.com, GitHub
https://stackoverflow.com, Stack Overflow
Format: URL, Title
Links widget features:
The Pages widget displays links to your static pages. Configuration is in config/widgets.txt
:
pages
Pages widget data:
Pages are defined in config/pages.txt
with one page per line:
about
contact
mission
board
Format: filename
(without .html extension)
Pages widget features:
pages/
directoryThe Featured Posts widget highlights specific posts. Configuration is in config/widgets.txt
:
featuredposts
Featured posts data:
Posts are defined in config/featuredposts.txt
with one post per line:
my-first-post
important-announcement
tutorial-series-part-1
Format: post_id
or post_id Title
(title is optional)
Featured posts features:
While in theory, a widget can be placed in any container, typically they will go in a sidebar (left or right). Putting a widget anywhere else has not been tested, and you will be on your own.
Widget configuration example:
# In config/widgets.txt
links
pages
featuredposts
This enables all three available widgets. The layout system determines where they appear.
Each widget requires a corresponding data file in the config/
directory:
Example data files:
config/links.txt
:
https://ruby-lang.org, Ruby Language
https://github.com, GitHub
config/pages.txt
:
about
contact
mission
config/featuredposts.txt
:
my-first-post
important-announcement
Widgets generate HTML files in widgets/<widgetname>/<widgetname>-card.html
that can be customized. Each widget uses Bootstrap styling and can be modified through CSS classes.
The front page layout system provides flexibility while maintaining consistency across your site. By combining different containers and widgets, you can create a front page that perfectly suits your content and audience.
**[Errors here - fix later. HF]
Creating new posts is one of the most common tasks in Scriptorium. Posts are the core content of your blog or website.
The easiest way to create a post is through the Scriptorium interactive shell:
scriptorium
Once in the shell, you have two options for creating content:
Create a draft:
new draft My First Blog Post
Create a post directly:
new post My First Blog Post
Drafts are temporary files for working on content:
drafts/
directoryYYYYMMDD-HHMMSS-draft.lt3
list drafts
to see all draftsnew draft
to create a draftPosts are the final published content:
posts/
directoryposts/0123/
(4-digit padded numbers)list posts
to see all postsnew post
to create a post directlyEach post consists of a directory with the following structure:
Post directory: posts/0123/
Post metadata file: posts/0123/meta.txt
Posts use LiveText format (see Section 3 for details). A typical post structure:
.h1 My First Blog Post
.h2 subtitle: Getting Started with Scriptorium
.p This is my first blog post using Scriptorium.
.h2 Why Scriptorium?
.p Scriptorium makes blogging simple and powerful.
.list
**Easy to use** - Simple command-line interface
**Flexible** - Multiple views and themes
**Fast** - Static site generation
**Customizable** - LiveText templating system
.end
.p That's it for my first post!
To see all posts in your current view:
list posts
This shows:
To see all drafts:
list drafts
This shows:
To edit an existing post, you'll need to open the post file directly in your editor. Posts are stored in posts/0123/source.lt3
.
Post numbers are sequential integers with 4-digit padding:
You can find post numbers by:
list posts
to see all postsposts/
directoryTo delete a post, Scriptorium moves the post directory to a deleted state:
posts/0001/
posts/_0001/
(with underscore prefix)To restore a deleted post, move the directory back from posts/_0001/
to posts/0001/
.
Posts can be in different states:
_0001/
directory)You can link between posts using their post numbers:
.p Check out my [previous post](posts/0001.html) for more information.
To link to a post in a different view:
.p See my [technical blog post](../tech/posts/0005.html) for more details.
The unlink_post
command removes a post from the current view but doesn't delete the post itself. It has no other effect on the post.
Featured posts appear in the Featured Posts widget (see Section 4). To feature a post:
widgets/featuredposts/list.txt
1
5
10
Posts appear in the Featured Posts widget in the order listed in widgets/featuredposts/list.txt
.
To remove a post from featured status:
widgets/featuredposts/list.txt
Scriptorium automatically assigns sequential post numbers:
Posts are typically displayed in chronological order (newest first), but you can customize this through:
While Scriptorium doesn't have built-in categories, you can organize posts by:
new post "Post Title"
generate
to build the final sitedeploy
to publish to your servernew draft "Draft Title"
Regular post maintenance tasks:
list posts
to see all postslist drafts
to see all draftsMost of this is intuitive. If it's not, the software probably was written incorrectly.
Pages in Scriptorium are static HTML files that provide additional content beyond your blog posts. They're perfect for creating "About" pages, contact information, documentation, or any other static content you want to make available on your site.
Pages can be linked directly in your site's navigation bar. This is typically configured in the header section of your view.
To add a page to your navbar:
Create the page file in your view's pages/
directory:
scriptorium edit pages/about.html
Configure the navbar in your view's header configuration:
scriptorium edit config/header.txt
Add navigation links to your header configuration file. The exact format depends on your theme, but typically looks like:
# Navigation links
.nav-link "About" "pages/about.html"
.nav-link "Contact" "pages/contact.html"
The navbar will automatically include these links, making your pages easily accessible from any part of your site.
Pages can also be displayed using the Pages widget, which creates a sidebar or footer list of your pages. This is useful for organizing related content or providing quick access to important pages.
To set up the Pages widget:
Create the widget configuration:
scriptorium edit widgets/pages/list.txt
Add page references to the list file. Each line should contain the page filename (without the .html
extension):
about
contact
documentation
Generate the widget:
scriptorium generate widget pages
The Pages widget will automatically:
<title>
tags or <h1>
tags)Pages can link to each other and to blog posts using internal links. This creates a connected web of content within your site.
In your page HTML, use JavaScript-based links that work with Scriptorium's navigation system:
<a href="javascript:void(0)" onclick="load_main('pages/other-page.html')">Link to Another Page</a>
You can also link from pages to specific blog posts:
<a href="javascript:void(0)" onclick="load_main('posts/post-slug.html')">Link to Blog Post</a>
In your blog posts, you can link to pages using the same pattern:
<a href="javascript:void(0)" onclick="load_main('pages/about.html')">About Us</a>
For better organization, you can create subdirectories under the pages/
directory. This is useful for grouping related pages or creating more complex site structures.
# Create a subdirectory
mkdir pages/documentation
# Create pages within the subdirectory
scriptorium edit pages/documentation/getting-started.html
scriptorium edit pages/documentation/advanced-usage.html
When linking to pages in subdirectories, include the full path:
<a href="javascript:void(0)" onclick="load_main('pages/documentation/getting-started.html')">Getting Started</a>
In your widgets/pages/list.txt
file, you can reference subdirectory pages using relative paths:
about
contact
documentation/getting-started
documentation/advanced-usage
about.html
, contact.html
, privacy-policy.html
<title>
tags in your HTML for better widget integrationPages inherit the same styling as your main site, so they'll automatically match your theme. You can include additional CSS or JavaScript in individual pages if needed, but it's generally better to keep styling consistent across your site.
Since pages are static HTML files, you can edit them using any text editor or HTML editor. Scriptorium provides convenient commands for common page operations:
# Create a new page
scriptorium edit pages/new-page.html
# List all pages in a view
ls views/your-view/pages/
# Generate all content (including pages)
scriptorium generate
Pages are a powerful way to extend your Scriptorium site beyond just blog posts, allowing you to create a complete website with multiple types of content.
Scriptorium is designed to be highly customizable while maintaining simplicity. You can modify themes, create custom templates, and extend functionality through widgets and features.
Themes in Scriptorium control the overall look and feel of your site. Currently, Scriptorium comes with a "standard" theme, but you can clone and customize it to create your own unique design.
A theme consists of several components:
To create your own theme:
Navigate to the themes directory:
cd themes
Clone the standard theme:
cp -r standard my-custom-theme
Update your view to use the new theme:
scriptorium edit config.txt
Change the theme line to:
theme: my-custom-theme
The main styling is controlled by CSS files in your theme:
layout.css
: Overall layout and responsive designtext.css
: Typography and text stylingbootstrap.css
: Bootstrap framework (if used)To modify the appearance:
Edit the CSS files in your theme directory:
scriptorium edit themes/my-custom-theme/layout/gen/layout.css
scriptorium edit themes/my-custom-theme/layout/gen/text.css
Common customizations:
Regenerate your site to see changes:
scriptorium generate
Understanding the theme directory structure helps with customization:
my-custom-theme/
├── assets/ # Images, fonts, etc.
├── config.txt # Theme configuration
├── header/ # Header templates
├── initial/ # Initial content templates
├── layout/ # Layout templates and CSS
│ ├── config/ # Layout configuration files
│ ├── gen/ # Generated CSS files
│ └── layout.txt # Layout structure
└── templates/ # Main templates
├── index.lt3 # Front page template
├── post.lt3 # Individual post template
└── widget.lt3 # Widget template
Scriptorium themes are designed to work on various screen sizes. When customizing:
Templates control how your content is structured and displayed. Scriptorium uses LiveText templates (.lt3
files) that combine HTML structure with dynamic content.
The core templates in your theme:
templates/index.lt3
: Front page layouttemplates/post.lt3
: Individual blog post layouttemplates/widget.lt3
: Widget container layoutTo modify how blog posts are displayed:
Edit the post template:
scriptorium edit themes/my-custom-theme/templates/post.lt3
Available variables in post templates:
%{post.title}
: Post title%{post.body}
: Post content%{post.pubdate}
: Publication date%{post.tags}
: Post tags%{post.blurb}
: Post excerptExample template structure:
<article class="post">
<header>
<h1>%{post.title}</h1>
<time>%{post.pubdate}</time>
</header>
<div class="content">
%{post.body}
</div>
<footer>
<div class="tags">%{post.tags}</div>
</footer>
</article>
The front page template controls how your blog index is displayed:
Edit the index template:
scriptorium edit themes/my-custom-theme/templates/index.lt3
Common customizations:
You can override specific templates for individual views:
Create a view-specific template:
scriptorium edit views/my-view/templates/post.lt3
The view-specific template will be used instead of the theme template for that view
Templates use LiveText syntax for dynamic content:
%{variable_name}
.if condition
... .end
.each item
... .end
.include "file.lt3"
Widgets are modular components that add functionality to your site. Scriptorium comes with several built-in widgets, and you can create custom ones.
Displays a list of external links in a sidebar:
Configure the widget:
scriptorium edit widgets/links/list.txt
Add links in the format url, title
:
https://example.com, Example Site
https://github.com, GitHub Profile
Generate the widget:
scriptorium generate widget links
Lists internal pages (see Section 6 for details):
Configure the widget:
scriptorium edit widgets/pages/list.txt
Add page references:
about
contact
documentation
Highlights specific posts in a sidebar:
Configure the widget:
scriptorium edit widgets/featuredposts/list.txt
Add post references:
001 My Important Post
002 Another Featured Post
To include widgets in your site:
Edit your layout configuration:
scriptorium edit config/layout.txt
Add widget containers to your layout:
header
left 20%
main
right 20%
footer
Configure the sidebar to include widgets:
scriptorium edit config/left.txt
Add widget references:
.widget links
.widget pages
.widget featuredposts
For advanced customization, you can create your own widgets:
Create a widget directory:
mkdir -p widgets/my-custom-widget
Create the widget configuration:
scriptorium edit widgets/my-custom-widget/config.txt
Create the widget template:
scriptorium edit widgets/my-custom-widget/template.lt3
Register the widget in your view's configuration
Widgets inherit styling from your theme, but you can add custom CSS:
Create widget-specific CSS:
scriptorium edit themes/my-custom-theme/assets/widgets.css
Include the CSS in your layout templates
Common issues and solutions:
scriptorium generate
to rebuildScriptorium includes several advanced features that extend its functionality beyond basic blogging. These features help you integrate with external platforms and enhance your site's social presence.
Scriptorium includes built-in Reddit integration that allows you to automatically share your blog posts to Reddit. This feature helps increase your content's visibility and drive traffic to your site.
Before you can use Reddit integration, you need to create a Reddit application and configure your credentials:
Create a Reddit application:
Configure Reddit credentials:
scriptorium edit config/reddit.json
Add your Reddit credentials to the configuration file:
{
"client_id": "your_client_id_here",
"client_secret": "your_client_secret_here",
"username": "your_reddit_username",
"password": "your_reddit_password",
"user_agent": "scriptorium-bot/1.0"
}
Set appropriate permissions for the configuration file:
chmod 600 config/reddit.json
Once configured, you can automatically post to Reddit when you publish blog posts:
Add Reddit metadata to your blog posts:
.title My Blog Post Title
.reddit_subreddit programming
.reddit_title My Blog Post Title
.reddit_flair "Discussion"
Available Reddit metadata:
.reddit_subreddit
: Target subreddit (e.g., "programming", "webdev").reddit_title
: Custom title for Reddit (optional, uses post title if not specified).reddit_flair
: Post flair (optional).reddit_nsfw
: Mark as NSFW (true/false).reddit_spoiler
: Mark as spoiler (true/false)Publish your post:
scriptorium publish 001
The post will automatically be shared to Reddit with the specified metadata
Common issues and solutions:
config/reddit.json
Scriptorium includes several features to enhance your social media presence and make your content more shareable.
Add social media metadata to your posts to improve how they appear when shared:
.title My Blog Post Title
.og_title My Blog Post Title
.og_description A compelling description of my blog post
.og_image /assets/my-featured-image.jpg
.twitter_card summary_large_image
.twitter_title My Blog Post Title
.twitter_description A compelling description for Twitter
.twitter_image /assets/my-featured-image.jpg
Open Graph tags control how your content appears when shared on Facebook, LinkedIn, and other platforms:
.og_title
: Title for social media shares.og_description
: Description for social media shares.og_image
: Featured image for social media shares.og_type
: Content type (article, website, etc.).og_url
: Canonical URL for the contentTwitter Card tags optimize your content for Twitter sharing:
.twitter_card
: Card type (summary, summary_large_image, app, player).twitter_title
: Title for Twitter shares.twitter_description
: Description for Twitter shares.twitter_image
: Image for Twitter shares.twitter_site
: Your Twitter username.twitter_creator
: Content creator's Twitter usernameAdd social sharing buttons to your posts:
Configure social sharing in your theme:
scriptorium edit themes/my-theme/templates/post.lt3
Add sharing buttons to your post template:
<div class="social-share">
<a href="https://twitter.com/intent/tweet?url=%{post.url}&text=%{post.title}" target="_blank">Share on Twitter</a>
<a href="https://www.facebook.com/sharer/sharer.php?u=%{post.url}" target="_blank">Share on Facebook</a>
<a href="https://www.linkedin.com/sharing/share-offsite/?url=%{post.url}" target="_blank">Share on LinkedIn</a>
</div>
Scriptorium automatically generates RSS feeds for your content:
your-site.com/feed.xml
your-site.com/category/feed.xml
your-site.com/tag/feed.xml
Set up email subscriptions for your blog:
Configure email settings:
scriptorium edit config/email.txt
Add subscription form to your site:
<form action="/subscribe" method="post">
<input type="email" name="email" placeholder="Enter your email">
<button type="submit">Subscribe</button>
</form>
Track your site's performance with analytics:
Google Analytics:
scriptorium edit config/analytics.txt
Add your Google Analytics tracking code:
GA_TRACKING_ID: UA-XXXXXXXXX-X
Other analytics services:
Automate your social media presence:
When using social media features:
Common issues and solutions:
Once you've created your Scriptorium site, you'll want to deploy it to make it accessible on the web. This section covers various deployment options, from local development to production hosting.
Before deploying to a server, you'll typically want to test your site locally to ensure everything works correctly.
Scriptorium generates static files that can be served by any web server. For local development:
Generate your site:
scriptorium generate
Start a local web server:
# Using Python (if available)
cd output
python -m http.server 8000
# Using Ruby (if available)
cd output
ruby -run -e httpd . -p 8000
# Using Node.js (if available)
cd output
npx serve -p 8000
Access your site at http://localhost:8000
For a better development experience with automatic reloading:
Install a live reload server:
# Using Node.js
npm install -g live-server
# Or using Python
pip install livereload
Start the development server:
cd output
live-server --port=8000
Your browser will automatically refresh when you make changes to your site
During development, you may want to test different views:
Switch between views:
scriptorium view view-name
Generate the specific view:
scriptorium generate
Test the view in your local development server
Common local development issues and solutions:
scriptorium generate
after changesWhen you're ready to deploy your site to production, you have several hosting options available.
Static hosting services are ideal for Scriptorium sites since they generate static HTML files:
Create a GitHub repository for your site
Push your Scriptorium repository to GitHub:
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/repository-name.git
git push -u origin main
Enable GitHub Pages in your repository settings
Configure GitHub Actions for automatic deployment (optional)
scriptorium generate
output
scriptorium generate
output
For traditional web hosting providers:
Generate your site:
scriptorium generate
Upload files to your web server:
# Using rsync (recommended)
rsync -avz output/ user@your-server.com:/path/to/web/root/
# Using scp
scp -r output/* user@your-server.com:/path/to/web/root/
# Using FTP/SFTP client
# Upload all files from the output directory
Set proper permissions:
chmod 644 output/*.html
chmod 644 output/*.css
chmod 644 output/*.js
chmod 755 output/
For more control, deploy to a Virtual Private Server:
Set up your VPS with a web server (Apache, Nginx, etc.)
Install required dependencies:
# Ubuntu/Debian
sudo apt update
sudo apt install nginx ruby ruby-dev
# CentOS/RHEL
sudo yum install nginx ruby ruby-devel
Configure your web server to serve static files
Set up automatic deployment with Git hooks or CI/CD
Automate your deployment process:
Create a deployment script:
#!/bin/bash
# deploy.sh
# Generate the site
scriptorium generate
# Upload to server
rsync -avz --delete output/ user@your-server.com:/path/to/web/root/
# Clear cache (if using a CDN)
# curl -X POST https://api.cloudflare.com/client/v4/zones/zone-id/purge_cache
Make it executable:
chmod +x deploy.sh
Run deployment:
./deploy.sh
Configure your domain name to point to your hosted site.
Add DNS records in your domain registrar's control panel:
www
subdomain to your main domainExample DNS configuration:
Type Name Value
A @ 192.168.1.100
CNAME www yourdomain.com
Set up subdomains for different sections of your site:
Add subdomain DNS records:
Type Name Value
A blog 192.168.1.100
A docs 192.168.1.100
Configure web server to handle subdomains
Set up separate Scriptorium repositories for each subdomain (if needed)
Verify your domain is properly configured:
Check DNS propagation:
nslookup yourdomain.com
dig yourdomain.com
Test website accessibility:
curl -I http://yourdomain.com
Check for redirects and ensure they're working correctly
Secure your site with HTTPS using SSL certificates.
Install Certbot:
# Ubuntu/Debian
sudo apt install certbot python3-certbot-nginx
# CentOS/RHEL
sudo yum install certbot python3-certbot-nginx
Obtain SSL certificate:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Auto-renewal setup:
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet
For paid SSL certificates:
Generate CSR (Certificate Signing Request):
openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr
Submit CSR to your certificate provider
Install the certificate on your web server
Configure web server to use SSL
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
location / {
root /path/to/your/site;
index index.html;
try_files $uri $uri/ =404;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
<VirtualHost *:443>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
SSLEngine on
SSLCertificateFile /path/to/certificate.crt
SSLCertificateKeyFile /path/to/private.key
DocumentRoot /path/to/your/site
<Directory /path/to/your/site>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
Redirect permanent / https://yourdomain.com/
</VirtualHost>
Improve site performance with a CDN:
Before going live:
Even with the best setup, you may encounter issues while using Scriptorium. This section covers common problems and their solutions, helping you quickly resolve issues and get back to creating content.
Symptoms: Running scriptorium generate
fails or produces errors.
Possible causes and solutions:
Missing dependencies:
# Check if Ruby and required gems are installed
ruby --version
gem list
# Reinstall Scriptorium if needed
gem uninstall scriptorium
gem install scriptorium
Corrupted repository:
# Check repository integrity
scriptorium status
# If corrupted, restore from backup or recreate
cp -r .scriptorium .scriptorium.backup
scriptorium init
Permission issues:
# Check file permissions
ls -la
# Fix permissions if needed
chmod 755 .
chmod 644 *.txt *.md *.lt3
Symptoms: Posts exist but don't show up on the site.
Solutions:
Check post status:
scriptorium list posts
Verify post is linked to current view:
scriptorium post 001
# Check the "views" field
Link post to view if needed:
scriptorium link 001
Regenerate the site:
scriptorium generate
Symptoms: Images appear broken or don't load.
Solutions:
Check image paths:
# Verify image exists
ls -la assets/images/
# Check path in post
scriptorium edit posts/001.lt3
Correct image references:
# Use relative paths from the post

# Or absolute paths from site root

Ensure images are in the correct directory:
# Move images to assets directory
mv my-image.jpg assets/images/
Symptoms: Widget is configured but doesn't show on the site.
Solutions:
Check widget configuration:
scriptorium edit widgets/links/list.txt
# Verify the file exists and has content
Generate the widget:
scriptorium generate widget links
Check layout configuration:
scriptorium edit config/layout.txt
# Ensure sidebar containers are defined
scriptorium edit config/left.txt
# Ensure widget is referenced
Regenerate the entire site:
scriptorium generate
Symptoms: Changes to widget configuration don't appear on the site.
Solutions:
Regenerate the specific widget:
scriptorium generate widget widget-name
Clear any caching:
# Remove generated files
rm -rf output/
scriptorium generate
Symptoms: Site doesn't use the expected theme.
Solutions:
Check theme configuration:
scriptorium edit config.txt
# Verify theme: theme-name is set correctly
Verify theme exists:
ls -la themes/
# Ensure the theme directory exists
Apply theme explicitly:
scriptorium theme theme-name
Symptoms: Site appears unstyled or with broken styling.
Solutions:
Check CSS file paths:
ls -la themes/standard/layout/gen/
# Verify CSS files exist
Regenerate theme:
scriptorium generate
# This should regenerate CSS files
Check browser cache:
Symptoms: Scriptorium fails to run or has compatibility issues.
Solutions:
Check Ruby version:
ruby --version
# Scriptorium requires Ruby 2.7 or higher
Update Ruby if needed:
# Using rbenv
rbenv install 3.2.0
rbenv global 3.2.0
# Using rvm
rvm install 3.2.0
rvm use 3.2.0 --default
Reinstall gems:
gem update
gem install scriptorium
Symptoms: Scriptorium conflicts with other Ruby gems.
Solutions:
Use bundler:
# Create Gemfile
echo 'gem "scriptorium"' > Gemfile
# Install with bundler
bundle install
bundle exec scriptorium
Use gem isolation:
# Install in user directory
gem install --user-install scriptorium
Check gem environment:
gem env
# Verify gem paths and versions
Symptoms: Scriptorium fails due to missing system libraries.
Solutions:
Install development tools:
# Ubuntu/Debian
sudo apt install build-essential
# macOS
xcode-select --install
# CentOS/RHEL
sudo yum groupinstall "Development Tools"
Install specific libraries:
# Ubuntu/Debian
sudo apt install libssl-dev libreadline-dev zlib1g-dev
# CentOS/RHEL
sudo yum install openssl-devel readline-devel zlib-devel
Cause: Scriptorium can't find a required file.
Solution:
# Check if file exists
ls -la path/to/file
# Create missing file if needed
touch path/to/file
# Check file permissions
chmod 644 path/to/file
Cause: Widget name contains invalid characters.
Solution:
# Use only lowercase letters, numbers, and hyphens
# Good: my-widget, links, pages
# Bad: My_Widget, links!, pages@
Cause: Layout file contains unrecognized container names.
Solution:
# Check layout file
scriptorium edit config/layout.txt
# Valid containers: header, main, left, right, footer
# Remove or correct invalid container names
Cause: Referenced theme is not found.
Solution:
# List available themes
ls -la themes/
# Check theme configuration
scriptorium edit config.txt
# Use existing theme or create new one
scriptorium theme standard
Cause: Referenced post ID doesn't exist.
Solution:
# List all posts
scriptorium list posts
# Check post ID format
# Posts should be numbered: 001, 002, etc.
# Create post if needed
scriptorium new post "Post Title"
# Run commands with verbose output
scriptorium generate --verbose
# Check for detailed error messages
scriptorium status --verbose
# Look for error logs
find . -name "*.log" -exec cat {} \;
# Check system logs
tail -f /var/log/syslog # Linux
tail -f /var/log/system.log # macOS
# Test post generation
scriptorium generate post 001
# Test widget generation
scriptorium generate widget links
# Test theme application
scriptorium theme standard
Check the documentation:
Use built-in help:
scriptorium --help
scriptorium help command-name
Check the source code:
# Find Scriptorium installation
gem which scriptorium
# Explore the source
ls -la $(gem which scriptorium | sed 's/lib\/scriptorium.rb//')
GitHub repository:
Documentation:
Forums and discussions:
When reporting bugs, include:
System information:
ruby --version
gem list scriptorium
uname -a
Steps to reproduce:
Configuration details:
Error logs:
Before asking for help:
When asking for help:
Follow up:
Regular backups:
# Backup your Scriptorium repository
tar -czf scriptorium-backup-$(date +%Y%m%d).tar.gz .
Version control:
# Use git for version control
git init
git add .
git commit -m "Initial commit"
Test changes:
# Test changes before applying
scriptorium generate --dry-run
# Keep a test environment
cp -r . test-environment
Document your setup:
By following these troubleshooting steps and best practices, you can quickly resolve most issues and maintain a stable Scriptorium installation.
This section provides comprehensive reference information for Scriptorium, including command syntax, configuration options, and technical details.
scriptorium init [path]
Initialize a new Scriptorium repository.
Options:
path
: Directory to initialize (default: current directory)Examples:
scriptorium init # Initialize in current directory
scriptorium init my-blog # Initialize in my-blog directory
scriptorium new post "title"
Create a new blog post.
Options:
title
: Post title (required)Examples:
scriptorium new post "My First Post"
scriptorium new post "Getting Started with Scriptorium"
scriptorium edit [file]
Edit a file using the configured editor.
Options:
file
: File path to editExamples:
scriptorium edit posts/001.lt3
scriptorium edit config.txt
scriptorium edit widgets/links/list.txt
scriptorium generate [target]
Generate the site or specific components.
Options:
target
: Specific component to generate (optional)
post <id>
: Generate specific postwidget <name>
: Generate specific widgetview <name>
: Generate specific viewExamples:
scriptorium generate # Generate entire site
scriptorium generate post 001 # Generate specific post
scriptorium generate widget links # Generate links widget
scriptorium publish <id>
Publish a draft post.
Options:
id
: Post ID to publishExamples:
scriptorium publish 001
scriptorium publish 002
scriptorium list [type]
List posts, views, or other content.
Options:
type
: Type of content to list
posts
: List all postsviews
: List all viewsdrafts
: List draft postsExamples:
scriptorium list posts
scriptorium list views
scriptorium list drafts
scriptorium view <name>
Switch to a different view.
Options:
name
: View name to switch toExamples:
scriptorium view sample
scriptorium view blog
scriptorium create view <name> <title> [subtitle]
Create a new view.
Options:
name
: View nametitle
: View titlesubtitle
: View subtitle (optional)Examples:
scriptorium create view blog "My Blog" "Personal thoughts and ideas"
scriptorium create view docs "Documentation"
scriptorium link <id> [view]
Link a post to a view.
Options:
id
: Post IDview
: View name (default: current view)Examples:
scriptorium link 001
scriptorium link 002 blog
scriptorium unlink <id> [view]
Unlink a post from a view.
Options:
id
: Post IDview
: View name (default: current view)Examples:
scriptorium unlink 001
scriptorium unlink 002 blog
scriptorium delete <id>
Delete a post.
Options:
id
: Post ID to deleteExamples:
scriptorium delete 001
scriptorium generate widget <name>
Generate a specific widget.
Options:
name
: Widget name (links, pages, featuredposts)Examples:
scriptorium generate widget links
scriptorium generate widget pages
scriptorium theme <name>
Apply a theme to the current view.
Options:
name
: Theme nameExamples:
scriptorium theme standard
scriptorium theme custom
scriptorium status
Show repository status.
Examples:
scriptorium status
scriptorium help [command]
Show help information.
Options:
command
: Specific command to get help forExamples:
scriptorium help
scriptorium help generate
config/repo.txt
Main repository configuration file.
Example:
title: My Scriptorium Site
description: A personal blog and website
author: Your Name
email: your.email@example.com
url: https://example.com
config.txt
View-specific configuration.
Example:
title: My Blog
subtitle: Personal thoughts and ideas
theme: standard
layout: default
config/layout.txt
Layout configuration defining page structure.
Example:
header
left 20%
main
right 20%
footer
config/header.txt
Header configuration including navigation.
Example:
# Site title
.title My Blog
# Navigation links
.nav-link "Home" "/"
.nav-link "About" "pages/about.html"
.nav-link "Contact" "pages/contact.html"
widgets/links/list.txt
Links widget configuration.
Format:
url, title
url, title
Example:
https://example.com, Example Site
https://github.com, GitHub Profile
widgets/pages/list.txt
Pages widget configuration.
Format:
page-name
page-name
Example:
about
contact
documentation
widgets/featuredposts/list.txt
Featured posts widget configuration.
Format:
id title
id
Example:
001 My Important Post
002 Another Featured Post
003
themes/standard/config.txt
Theme configuration file.
Example:
name: Standard Theme
version: 1.0
description: Default Scriptorium theme
author: Scriptorium Team
**bold text**
*italic text*
`code text`
[link text](url)

.command
.command parameter
.command "parameter with spaces"
.command
content here
.end
.title Post Title
.subtitle Post Subtitle
.tags tag1, tag2, tag3
.blurb Post excerpt for summaries
.views view1, view2
.pubdate 2024-01-15
.og_title Title for social media
.og_description Description for social media
.og_image /path/to/image.jpg
.twitter_card summary_large_image
.twitter_title Twitter title
.twitter_description Twitter description
.reddit_subreddit programming
.reddit_title Custom Reddit title
.reddit_flair "Discussion"
.reddit_nsfw false
.reddit_spoiler false
%{post.title} # Post title
%{post.body} # Post content
%{post.pubdate} # Publication date
%{post.tags} # Post tags
%{post.blurb} # Post excerpt
%{post.url} # Post URL
%{post.slug} # Post slug
%{site.title} # Site title
%{site.description} # Site description
%{site.url} # Site URL
%{site.author} # Site author
%{view.name} # View name
%{view.title} # View title
%{view.subtitle} # View subtitle
.if condition
content
.end
.if post.tags.include?("featured")
This is a featured post!
.end
.each item in collection
content
.end
.each post in posts
%{post.title}
.end
.include "file.lt3"
.include "templates/header.lt3"
Main repository class for managing Scriptorium sites.
Methods:
# Initialize repository
repo = Scriptorium::Repo.open(path)
# Create new repository
repo = Scriptorium::Repo.create(path, title, description)
# Get current view
view = repo.current_view
# List all views
views = repo.views
# Create post
post = repo.create_post(title: "Title", body: "Content")
# Get post by ID
post = repo.post(id)
# List all posts
posts = repo.all_posts
Represents a view within a repository.
Methods:
# Get view name
name = view.name
# Get view title
title = view.title
# Get view directory
dir = view.dir
# Generate view
view.generate
# Apply theme
view.apply_theme(theme_name)
Represents a blog post.
Methods:
# Get post title
title = post.title
# Get post body
body = post.body
# Get post tags
tags = post.tags
# Get post views
views = post.views
# Update post
post.update(fields)
# Delete post
post.delete
Links widget for displaying external links.
Methods:
# Get list of links
links = widget.get_list
# Generate widget
widget.generate
# Get widget card content
card = widget.card
Pages widget for displaying internal pages.
Methods:
# Generate widget
widget.generate
# Get widget card content
card = widget.card
Featured posts widget for highlighting specific posts.
Methods:
# Parse featured line
post_id, title = widget.parse_featured_line(line)
# Get post title
title = widget.get_post_title(post_id)
# Generate widget
widget.generate
# Read file
content = read_file(path)
# Write file
write_file(path, content)
# Check if file exists
exists = file_exist?(path)
# Make directory
make_dir(path)
# Generate HTML card
html = html_card(title, tag, content)
# Generate HTML container
html = html_container(content)
# Generate HTML body
html = html_body(css) { content }
repository/
├── config/
│ ├── repo.txt # Repository configuration
│ ├── deploy.txt # Deployment configuration
│ └── widgets.txt # Available widgets
├── views/
│ ├── sample/ # Sample view
│ │ ├── config.txt # View configuration
│ │ ├── config/ # View-specific config
│ │ ├── posts/ # Post files
│ │ ├── pages/ # Page files
│ │ ├── widgets/ # Widget configurations
│ │ ├── themes/ # View-specific themes
│ │ ├── layout/ # Layout files
│ │ ├── output/ # Generated output
│ │ └── staging/ # Staging area
│ └── other-view/ # Additional views
├── themes/
│ └── standard/ # Standard theme
│ ├── config.txt # Theme configuration
│ ├── assets/ # Theme assets
│ ├── templates/ # Theme templates
│ └── layout/ # Theme layout
├── posts/ # Global posts
├── drafts/ # Draft posts
└── .scriptorium # Repository metadata
view/
├── config.txt # View configuration
├── config/ # Configuration files
│ ├── layout.txt # Layout configuration
│ ├── header.txt # Header configuration
│ ├── left.txt # Left sidebar configuration
│ ├── right.txt # Right sidebar configuration
│ ├── main.txt # Main content configuration
│ └── footer.txt # Footer configuration
├── posts/ # Post files
│ ├── 001.lt3 # Post 001
│ ├── 002.lt3 # Post 002
│ └── ... # Additional posts
├── pages/ # Page files
│ ├── about.html # About page
│ ├── contact.html # Contact page
│ └── ... # Additional pages
├── widgets/ # Widget configurations
│ ├── links/ # Links widget
│ │ └── list.txt # Links list
│ ├── pages/ # Pages widget
│ │ └── list.txt # Pages list
│ └── featuredposts/ # Featured posts widget
│ └── list.txt # Featured posts list
├── themes/ # View-specific themes
├── layout/ # Layout files
│ ├── header.html # Header template
│ ├── footer.html # Footer template
│ └── ... # Additional layout files
├── output/ # Generated output
│ ├── index.html # Front page
│ ├── posts/ # Generated post pages
│ ├── pages/ # Generated page files
│ ├── assets/ # Assets (CSS, JS, images)
│ └── widgets/ # Generated widget files
└── staging/ # Staging area
theme/
├── config.txt # Theme configuration
├── assets/ # Theme assets
│ ├── images/ # Theme images
│ ├── fonts/ # Theme fonts
│ └── ... # Additional assets
├── templates/ # Theme templates
│ ├── index.lt3 # Front page template
│ ├── post.lt3 # Post template
│ └── widget.lt3 # Widget template
├── layout/ # Theme layout
│ ├── config/ # Layout configuration
│ ├── gen/ # Generated files
│ └── layout.txt # Layout structure
├── header/ # Header templates
├── initial/ # Initial content
└── ... # Additional theme files
NNN-title.lt3
(e.g., 001-my-first-post.lt3
)name.html
(e.g., about.html
, contact.html
)list.txt
or config.txt
widget-name-card.html
config.txt
.lt3
extensionThis reference section provides the technical details needed for advanced Scriptorium usage and development. For more specific information about certain areas, consult the relevant sections of this user guide or the Scriptorium source code.
FAQs
Unknown package
We found that scriptorium demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.