Commands
The examples below assume the static binary is in your project directory and use ./yiipress so they work without changing PATH. Source checkouts expose the same commands through ./yii; engine contributors should run them through the repository make targets.
build
Generates static HTML content from source files.
./yiipress build [--content-dir=content] [--output-dir=output] [--workers=auto] [--no-cache] [--drafts] [--future] [--dry-run] [--no-write] [--profile]
Options:
--content-dir,-c— path to the content directory (default:content). Absolute or relative to project root.--output-dir,-o— path to the output directory (default:output). Absolute or relative to project root.--workers,-w— number of parallel workers orauto(default:auto). Auto mode detects available CPU capacity inside the container, caps it at4, and still falls back to sequential work for small task sets.--no-cache— disable build cache and incremental builds. Forces a full rebuild. Fresh or empty output directories are written directly. Existing non-empty output directories are replaced only if they contain the.yiipress-buildmarker written by previous builds; in that case the rebuild is written to a temporary sibling directory and swapped in after generation succeeds.--drafts— include draft entries in the build. By default, entries withdraft: truein front matter are excluded from HTML output, feeds, and sitemap.--future— include future-dated entries in the build. By default, entries with a date in the future are excluded from HTML output, feeds, and sitemap.--dry-run— list all files that would be generated without writing anything. The output directory is not created or modified.--no-write— run the full render/generation path without writing site output files. This is intended for performance diagnostics: unlike--dry-run, it renders entries, templates, feeds, listings, archives, sitemap data, search data, taxonomy pages, and author pages. Build cache and incremental manifest writes are skipped.--profile— print phase timings for the real build path. Use this before and after optimization work to see which build phases moved.
Incremental builds
By default, subsequent builds are incremental — only changed source files are re-rendered and re-written. A build manifest tracks source file hashes between builds. Source installs store it under runtime/cache/; PHAR and static binary runs store it under the OS temp directory, keyed by the current project directory. If no files changed, the build exits immediately with "No changes detected".
Aggregate pages (feeds, listings, archives, sitemap, taxonomy, author pages) are always regenerated since they depend on the full entry set.
If config files (config.yaml, navigation.yaml, _collection.yaml) change, a full rebuild is triggered automatically.
Use --no-cache to force a full rebuild.
Build diagnostics
During the build, diagnostics are run on all entries and standalone pages. Warnings are printed before output generation:
- Broken internal links — markdown links to
.mdfiles that don't resolve to any known entry or page. - Missing images —
references to local files that don't exist in the content directory. - Unknown authors —
authorsfront matter values that don't match any author file incontent/authors/. - Empty taxonomy values — empty strings in
tagsorcategoriesarrays.
Diagnostics are informational and do not prevent the build from completing.
The command:
- Parses site config, navigation, collections, authors, and entries from the content directory.
- Runs build diagnostics and prints warnings.
- Prepares output writing. Incremental builds skip unchanged entries; full non-incremental builds write directly to fresh or empty output directories, and use a temporary output directory only when replacing existing marked build output.
- Renders collection entries — converts markdown to HTML via
ext-mdparser, applies the entry template, writes each entry asindex.htmlat its resolved permalink path. Drafts and future-dated entries are excluded by default. - Renders standalone pages — markdown files in the content root directory (e.g.,
contact.md→/contact/). - Copies content assets (images, SVGs, etc.) to the output directory.
- Generates site-wide Atom (
/feed.xml), RSS 2.0 (/rss.xml), and JSON Feed (/feed.json) feeds, plus Atom (feed.xml), RSS 2.0 (rss.xml), and JSON Feed (feed.json) feeds for each collection withfeed: true, capped by collectionfeed_limit(20by default,0for unlimited). - Generates paginated collection listing pages (e.g.,
/blog/,/blog/page/2/) for collections withlisting: true. - Generates
sitemap.xmlcontaining all entry URLs, standalone page URLs, collection listing URLs, and the home page. - Generates taxonomy pages for each taxonomy defined in
config.yaml(e.g.,/tags/,/tags/php/,/tags/php/page/2/,/categories/).
With --workers=N (N > 1), entry rendering and writing is parallelized across N forked processes. With --workers=auto, YiiPress uses up to the detected worker count and lets page writers clamp back to sequential mode for smaller workloads. Feeds are generated after entry writing and can be split per collection across workers. Sitemap generation remains serial.
check:links
Checks generated HTML output for broken local links, missing src targets, and missing anchor fragments.
./yiipress check:links [--output-dir=output] [--external]
Options:
--output-dir,-o— path to the generated output directory (default:output). Absolute or relative to project root.--external— also validate externalhttp://andhttps://links. This performs network requests, so it is opt-in.
Run build first, then check:links against the generated output. Local checks are filesystem-only and validate links such as ./guide/, /assets/site.css, and #heading-id.
serve
Starts the preview server for local development.
./yiipress serve [address] [--content-dir=content] [--output-dir=output] [--port=19777] [--workers=2]
Options:
--content-dir,-c— path to the content directory (default:content). Absolute or relative to project root.--output-dir,-o— path to the output directory served by the preview server (default:output). Absolute or relative to project root.--port,-p— port to serve at when the address argument does not include a port (default:19777).--workers,-w— number of preforked server workers (default:2).
On startup, serve prints the URL it is listening on. Build progress is printed by rebuilds triggered after file changes. Content and output paths resolve from the current working directory, so run the binary from the site directory or pass explicit --content-dir and --output-dir paths.
HTML pages served by serve include a fixed bottom-right Edit button. It opens the markdown source file for the current page using the editor command from content/config.yaml; when editor is omitted, YiiPress uses the platform default opener (open, xdg-open, or Windows start). The button resolves source files through the build manifest, so it is available for entry and standalone markdown pages and hidden failures are reported in the browser console.
Before starting the server, serve verifies that the content directory exists and that the output directory exists or can be created and written to. If the check fails, pass explicit paths, for example ./yiipress serve --content-dir=content --output-dir=output.
See Preview for static file serving and live reload behavior. Implementation details are in Engine.
init
Initializes a content directory with the minimal YiiPress structure:
config.yamlnavigation.yamlpage/_collection.yamlblog/_collection.yaml
./yiipress init [--content-dir=content]
Options:
--content-dir,-c— path to the content directory to create (default:content). Absolute or relative to project root.
The command creates parent directories as needed and fails if any scaffolded file already exists.
theme:init
Initializes editable theme files in the project from a bundled theme.
./yiipress theme:init [target-dir] [--theme=minimal] [--content-dir=content]
Arguments:
target-dir— directory to initialize theme files in (default:themes/custom). Absolute or relative to project root.
Options:
--theme,-t— bundled theme name to use as the source (default:minimal).--content-dir,-c— path to the content directory containingconfig.yaml(default:content). Absolute or relative to project root.
The command creates parent directories as needed, fails if any target file already exists, and updates config.yaml to use the initialized theme. The theme name is derived from the target directory name, so the default target themes/custom sets theme: "custom".
new
Scaffolds a new content entry or standalone page.
./yiipress new <title> [--collection=<name>] [--content-dir=content] [--draft]
Arguments:
title— title of the new entry (required).
Options:
--collection,-c— collection to create the entry in. If omitted, creates a standalone page in the content root.--content-dir,-d— path to the content directory (default:content).--draft— mark the entry as a draft (draft: truein front matter).
Behavior:
- For collections with
sort_by: date, the filename is prefixed with today's date (e.g.,2024-03-15-my-post.md). - For other collections, the filename is the slugified title (e.g.,
my-post.md). - Standalone pages get a
permalinkfield set to/<slug>/. - If
default_authoris set inconfig.yaml, it is added to theauthorsfront matter. - The command fails if the target file already exists or the collection is not found.
Examples:
./yiipress new "My First Post" --collection=blog ./yiipress new "Draft Ideas" --collection=blog --draft ./yiipress new "About Us"
import
Imports content from external sources into a YiiPress collection.
./yiipress import <source> [--collection=blog] [--content-dir=content] [--<importer-options>...]
Arguments:
source— source type to import from (required). Currently supported:ghost,hugo,jekyll,medium,telegram,wordpress.
Common options:
--collection,-c— target collection name (default:blog).--content-dir,-d— path to the content directory (default:content).
Each importer declares its own options (see below). The command dynamically registers them based on the selected source.
Behavior:
- Each importer reads source-specific data and converts it to markdown files with front matter.
- If the target collection directory doesn't exist, it is created along with a default
_collection.yaml. - Existing
_collection.yamlfiles are not overwritten. - Media files (photos, attachments) are copied to the collection's
assets/directory.
Telegram import
Imports messages from a Telegram Desktop channel export. Export a channel via Telegram Desktop: Settings > Advanced > Export Telegram data (select JSON format).
Importer options:
--directory— path to the Telegram export directory containingresult.json(required). Absolute or relative to project root.
The importer reads result.json from the export directory and converts each message to a markdown file:
- Hashtags →
tagsin front matter (e.g.,#phpbecomes tagphp). Hashtags are removed from the body text. - Bold →
**text** - Italic →
*text* - Strikethrough →
~~text~~ - Inline code →
`code` - Pre-formatted blocks → fenced code blocks
- Text links → converted to standard Markdown link syntax
- Photos → copied to
assets/and referenced with root-relative asset paths
The title is extracted from the first line of the message. The filename is prefixed with the message date (e.g., 2024-03-15-my-post.md).
Supports both single-chat exports (result.json with messages array) and full exports (result.json with chats.list structure).
Examples:
./yiipress import telegram --directory=/path/to/telegram-export ./yiipress import telegram --directory=/path/to/telegram-export --collection=channel ./yiipress import telegram --directory=./telegram-data --content-dir=content
Medium Markdown import
Imports Markdown files from a Medium Markdown export directory. The importer scans posts/ first when it exists, otherwise it scans the provided directory recursively.
Importer options:
--directory— path to the Medium Markdown export directory (required). Absolute or relative to project root.
The importer reads .md files and converts YAML front matter plus body content into YiiPress entries. It preserves title, date / published_at, canonical_url / url as origin, draft, published, tags, and categories. When metadata is missing, the title is inferred from the first # Heading or filename, and the date can be inferred from filenames starting with YYYY-MM-DD-.
Duplicate output filenames get numeric suffixes so earlier files are not overwritten.
Examples:
./yiipress import medium --directory=/path/to/medium-markdown-export ./yiipress import medium --directory=./medium --collection=blog
Ghost import
Imports posts and pages from a Ghost JSON export file. Export your site from Ghost Admin via Settings > Labs > Export your content.
Importer options:
--file— path to the Ghost.jsonexport file (required). Absolute or relative to project root.
The importer reads the standard db[0].data export structure and converts:
- Ghost posts (
type = post) into markdown files in the target collection. - Ghost pages (
type = page) into standalone markdown files in the content root. title,slug,published_at,status,custom_excerpt,feature_image, tags, authors, andhtmlinto YiiPress front matter and body content.
Published posts are imported normally. Non-published posts and pages are imported with draft: true. Unsupported post types are skipped. Duplicate output filenames get numeric suffixes so earlier files are not overwritten.
Examples:
./yiipress import ghost --file=/path/to/ghost-export.json ./yiipress import ghost --file=./ghost.json --collection=blog
WordPress import
Imports posts and pages from a WordPress WXR XML export file. Export your site from WordPress via Tools > Export > All content.
Importer options:
--file— path to the WordPress WXR.xmlexport file (required). Absolute or relative to project root.
The importer reads <item> records from the export and converts:
- WordPress posts (
wp:post_type = post) into markdown files in the target collection. - WordPress pages (
wp:post_type = page) into standalone markdown files in the content root. title,wp:post_date,link,excerpt:encoded,content:encoded,wp:status, categories, and tags into YiiPress front matter and body content.
Published posts are imported normally. Non-published posts and pages are imported with draft: true. Attachments, revisions, menu items, trashed posts, and auto-drafts are skipped. Duplicate output filenames get numeric suffixes so earlier files are not overwritten.
Examples:
./yiipress import wordpress --file=/path/to/wordpress-export.xml ./yiipress import wordpress --file=./export.xml --collection=blog
Jekyll import
Imports Markdown posts from a Jekyll site directory. The importer reads _posts/YYYY-MM-DD-slug.md and _posts/YYYY-MM-DD-slug.markdown files, converts common front matter fields, and writes YiiPress markdown files into the target collection.
Importer options:
--directory— path to the Jekyll site directory containing_posts(required). Absolute or relative to project root.
The importer preserves:
titledatepermalinktagscategories
If title is missing, it is inferred from the first # Heading in the post body and then from the filename slug.
Examples:
./yiipress import jekyll --directory=/path/to/jekyll-site ./yiipress import jekyll --directory=../old-blog --collection=blog
Hugo import
Imports Markdown content from a Hugo site directory. The importer scans content/posts/, then content/post/, then content/, reads .md files recursively, and writes YiiPress markdown files into the target collection.
Importer options:
--directory— path to the Hugo site directory (required). Absolute or relative to project root.
The importer supports YAML (---) and simple TOML (+++) front matter and preserves:
titledateurl/permalinkdrafttagscategories
If title is missing, it is inferred from the first # Heading in the post body and then from the filename slug. If date is missing, filenames starting with YYYY-MM-DD- provide the date.
Examples:
./yiipress import hugo --directory=/path/to/hugo-site ./yiipress import hugo --directory=../old-hugo-site --collection=blog
Adding custom importers
Importers implement YiiPress\Import\ContentImporterInterface and are registered via Yii3 DI in config/common/di/importer.php. Each importer declares its own options via the options() method. See Importing content for details.
clean / clear
Clears build output and caches.
./yiipress clean [--output-dir=output]
./yiipress clear [--output-dir=output]
Options:
--output-dir,-o— path to the output directory (default:output). Absolute or relative to project root.
The command removes:
- The output directory (default:
output/). - The build cache and incremental manifests. Source installs use
runtime/cache/; PHAR and static binary runs use a project-scoped cache under the OS temp directory.
If a directory does not exist, it is skipped with a notice.
yiipress / list
Shows available commands and help.