A powerful, feature-rich CLI blog engine built with Elixir. Manage your blog posts from the command line with an intuitive interface, persistent storage, and advanced features like tagging, search, and export/import capabilities.
- Quick Start Guide - Get started in 5 minutes
- API Documentation - Complete API reference
- Development Guide - Setup and workflow
- Architecture - Design and patterns
- Docker Guide - Docker usage and deployment
- Contributing - How to contribute
- Security Policy - Security guidelines
- Changelog - Version history
- Create, Read, Update, Delete (CRUD) - Full post management
- Tagging System - Organize posts with tags
- Search Functionality - Find posts by keywords in title, body, or tags
- Persistent Storage - Posts saved to JSON automatically
- Import/Export - Backup and share your posts
- Statistics - Track your blogging activity
- Multi-line Input - Write longer posts comfortably
- Timestamps - Automatic creation and update tracking
- Interactive CLI - User-friendly command-line interface
- Elixir 1.14 or higher
- Erlang/OTP 25 or higher
- Clone the repository:
git clone https://github.com/codeforgood-org/elixir-blog-engine.git
cd elixir-blog-engine- Install dependencies:
mix deps.get- Build the executable:
mix escript.build- Run the blog engine:
./blog_engineAlternatively, you can run directly with Mix:
mix run -e "BlogEngine.CLI.start()"Run with Docker (no Elixir installation needed):
# Build the image
docker build -t blog-engine .
# Run interactively
docker run -it --rm \
-v $(pwd)/priv/data:/app/priv/data \
blog-engine
# Or use docker-compose
docker-compose up blog-engineSee the Docker Guide for more details.
Common tasks with make:
make install # Install dependencies
make build # Build escript
make run # Build and run
make test # Run tests
make quality # Run format + lint
make ci # Run all CI checks
make docker-build # Build Docker image
make help # Show all commandsLoad sample posts to explore features:
# Import example posts
./scripts/import_examples.sh
# Or run the API demo
mix run scripts/demo.exs| Command | Description |
|---|---|
new |
Create a new post |
list |
List all posts |
view <id> |
View a post by ID |
edit <id> |
Edit a post by ID |
delete <id> |
Delete a post by ID |
search <query> |
Search posts by keyword |
tag <tag> |
List posts with a specific tag |
tags |
Show all tags and their counts |
export <path> |
Export all posts to a file |
import <path> |
Import posts from a file |
stats |
Show blog statistics |
help |
Show help message |
quit |
Exit the application |
> new
Title: Getting Started with Elixir
Body (empty line to finish):
Elixir is a dynamic, functional language designed for building
scalable and maintainable applications.
Tags (comma-separated, optional): elixir, tutorial, programming
✓ Post created successfully with ID 1
> list
=== All Posts ===
--------------------------------------------------------------------------------
[1] Getting Started with Elixir
2025-11-13 17:32:15 | Tags: elixir, tutorial, programming
--------------------------------------------------------------------------------
Total: 1 post(s)
> search elixir
=== Search Results for 'elixir' ===
--------------------------------------------------------------------------------
[1] Getting Started with Elixir
2025-11-13 17:32:15 | Tags: elixir, tutorial, programming
--------------------------------------------------------------------------------
Found: 1 post(s)
> stats
=== Blog Statistics ===
Total posts: 1
Total words: 12
Average words per post: 12
Total unique tags: 3
Oldest post: Getting Started with Elixir (2025-11-13 17:32:15)
Newest post: Getting Started with Elixir (2025-11-13 17:32:15)
mix testRun tests with coverage:
mix coverallsGenerate HTML coverage report:
mix coveralls.htmlFormat code:
mix formatRun static analysis with Credo:
mix credoRun type checking with Dialyzer:
mix dialyzermix docsDocumentation will be available in doc/index.html.
elixir-blog-engine/
├── lib/
│ ├── blog_engine.ex # Core business logic
│ └── blog_engine/
│ ├── cli.ex # Command-line interface
│ ├── post.ex # Post struct and functions
│ └── storage.ex # JSON persistence layer
├── test/
│ ├── blog_engine_test.exs
│ └── blog_engine/
│ ├── cli_test.exs
│ ├── post_test.exs
│ └── storage_test.exs
├── priv/
│ └── data/ # Persistent storage directory
│ └── posts.json # Saved posts (auto-generated)
├── config/
│ └── config.exs # Application configuration
├── mix.exs # Project configuration
├── .formatter.exs # Code formatter config
├── .credo.exs # Credo linter config
└── README.md
Posts are automatically saved to priv/data/posts.json in JSON format. The file is created automatically when you create your first post.
Export to a backup file:
> export ~/my-blog-backup.json
✓ Posts exported successfully to /home/user/my-blog-backup.json
Import from a backup:
> import ~/my-blog-backup.json
✓ Posts imported successfully from /home/user/my-blog-backup.json
We welcome contributions! Please see CONTRIBUTING.md for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and ensure they pass
- Format your code (
mix format) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
BlogEngine follows a clean, modular architecture:
- BlogEngine - Core module with business logic (CRUD operations, search, etc.)
- BlogEngine.Post - Post data structure and related functions
- BlogEngine.Storage - Handles JSON persistence
- BlogEngine.CLI - Interactive command-line interface
This separation of concerns makes the codebase:
- Easy to test
- Simple to maintain
- Straightforward to extend with new features
Future enhancements planned:
- Markdown support for post bodies
- Post categories
- Draft/published status
- Post scheduling
- Multiple storage backends (Markdown files, SQL)
- Web interface
- RSS feed generation
- Full-text search with ranking
- Post templates
- Bulk operations
This project is licensed under the MIT License - see the LICENSE file for details.
Built with:
- Elixir - The Elixir programming language
- Jason - JSON encoding/decoding
- ExUnit - Testing framework
- ExDoc - Documentation generation
- Credo - Static code analysis
- Dialyxir - Type checking
If you encounter any issues or have questions:
- Check the documentation
- Search existing issues
- Open a new issue
Made with ❤️ by the CodeForGood community