cable8mm / db-to-markdown
DB to markdown generator
Requires
- php: ^8.0.2
- cable8mm/array-flatten: ^1.0
- catfan/medoo: ^2.0
- league/html-to-markdown: ^5.0
- nesbot/carbon: ^2.72.0|^3.0
- symfony/console: ^6.0|^7.0
- vlucas/phpdotenv: ^5.0
Requires (Dev)
- fakerphp/faker: ^1.23
- laravel/pint: ^1.0
- phpunit/phpunit: ^9.0|^10.0|^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Convert WordPress posts to Markdown or Jekyll, or export content from any other database. This CLI reads a database table or view, converts HTML content to Markdown, and writes one file per record. Jekyll output includes YAML front matter.
It is not a WordPress plugin or a one-click site importer: you connect to the WordPress database and map the columns to export. For the standard WordPress schema, use a database view to select published posts and expose their categories alongside the post fields.
Convert WordPress to Jekyll
1. Expose published posts in a database view
The WordPress wp_posts table contains drafts, pages, revisions, and other records, and it does not contain category names directly. A view can filter to published posts and join their category slugs. Jekyll accepts categories as a space-separated string. Replace the wp_ prefix below if your site uses a different table prefix:
CREATE VIEW jekyll_posts AS SELECT p.ID AS id, p.post_title AS title, p.post_name AS slug, GROUP_CONCAT(DISTINCT t.slug ORDER BY t.slug SEPARATOR ' ') AS categories, p.post_content AS content, p.post_date AS published_at FROM wp_posts AS p LEFT JOIN wp_term_relationships AS tr ON tr.object_id = p.ID LEFT JOIN wp_term_taxonomy AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy = 'category' LEFT JOIN wp_terms AS t ON t.term_id = tt.term_id WHERE p.post_type = 'post' AND p.post_status = 'publish' GROUP BY p.ID, p.post_title, p.post_name, p.post_content, p.post_date;
2. Connect and map the view
Set your WordPress database credentials in .env:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_DATABASE=wordpress DB_USERNAME=your_database_user DB_PASSWORD=your_database_password DB_PORT=3306
Then map the view columns in db-to-markdown.json:
{
"table": "jekyll_posts",
"author": "Your Name",
"map": {
"title": "title",
"slug": "slug",
"categories": "categories",
"body": "content",
"published_at": "published_at"
}
}
3. Generate Jekyll posts
php bin/console create-jekyll
The command writes .markdown files with Jekyll front matter to dist/, for example:
--- layout: single title: "A WordPress post" date: 2024-06-15 14:30:00 categories: news updates author: Your Name --- The post body converted to Markdown.
The configured author is shared across the generated posts. WordPress shortcodes, custom fields, or per-post authors may need additional columns in the view and a custom command or body callback.
For a simpler source table or view that already has the required columns, skip the WordPress-specific view and follow the general table mapping below.
We have provided the API Documentation on the web. For more information, please visit https://www.palgle.com/db-to-markdown/ ❤️
Features
- Any schema can generate Markdown in any desired format
- Effortlessly incorporate your custom mapper and command
- Implement callback body and datetime functionality
- Database testing is supported
Preview
Support & Tested
| Versions | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| Available | ✅ | ✅ | ✅ | ✅ |
Installation
composer create-project cable8mm/db-to-markdown
After installation, run the init command to create the required configuration files:
php bin/console init
# Creates .env and db-to-markdown.json from their example templates
Configuration
1. Database Connection (.env)
Copy .env.example to .env and configure your database connection:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_DATABASE=your_database DB_USERNAME=root DB_PASSWORD=password DB_PORT=3306
If .env is not provided, SQLite is used by default with database/database.sqlite. You can customize the SQLite path by setting DB_DATABASE in your .env file. To skip database configuration entirely, leave .env out and use php bin/console seeding to seed the built-in SQLite database.
2. Table Mapping (db-to-markdown.json)
Configure your table structure and field mapping in db-to-markdown.json:
{
"table": "posts",
"author": "Your Name",
"category_labels": {
"1": "Category One",
"2": "Category Two"
},
"map": {
"title": ["title", "subtitle"],
"slug": "id",
"categories": "category_id",
"body": "content",
"published_at": "published_at"
}
}
Field Descriptions:
table: Your database table nameauthor: Default author name (used if author field is empty)category_labels: Maps category IDs to display names (optional)map.title: Column(s) for the article title (string or array)map.slug: Column for the URL slugmap.categories: Column for category mappingmap.body: Column containing HTML content (converted to Markdown)map.published_at: Published date column
Usage
Quick Start (SQLite Demo)
# Initialize configuration files php bin/console init # Seed demo data into the built-in SQLite database php bin/console seeding # Generate Markdown files php bin/console create-md # or for Jekyll format: php bin/console create-jekyll
Available Commands
# Generate standard Markdown files in dist/ php bin/console create-md # Generate Jekyll-compatible Markdown with YAML front matter php bin/console create-jekyll # Clear all generated files in dist/ php bin/console clean # Initialize configuration files from examples php bin/console init # Seed demo data for testing php bin/console seeding
Command Options
php bin/console create-md --dry-run # Shows how many files would be generated without writing them php bin/console create-md --limit=5 # Process only 5 records php bin/console create-md --limit=10 --offset=20 # Process 10 records starting from offset 20
How to Develop Custom Commands
-
Run init to create configuration files, or create them manually:
.envfor database credentialsdb-to-markdown.jsonfor table/field mapping
-
Create a mapper in
src/Mappers/to define your table field mapping (see existing examples). -
Create a format in
src/Formats/to define how output files are rendered (Markdown, Jekyll, etc.). -
Create a command in
src/Command/extendingBaseCommandor implementing your own logic. -
Register your command in
bin/console.
Formatting
composer lint # Modify all files to comply with the PSR-12. composer inspect # Inspect all files to ensure compliance with PSR-12.
Test
It uses the built-in SQLite database, not your own database. It will never cause harm to your data.
composer test
License
The DB to markdown project is open-sourced software licensed under the MIT license.
