cheinisch / markdown-editor
It's a simple Markdown editor (HTML/JS/CSS) packaged for easy embedding in PHP apps via Composer.
Package info
github.com/cheinisch/Markdown-Editor
Language:JavaScript
pkg:composer/cheinisch/markdown-editor
Requires
- php: >=8.0
- composer-plugin-api: ^2.0
Requires (Dev)
- composer/composer: ^2.0
README
A simple Markdown editor (HTML/JS/CSS) for easy embedding in PHP apps.
Requirements
- PHP >= 8.1
Installation
Copy src/MarkdownEditor.php and public/markdown-editor.js into your project — no further dependencies required.
your-project/
├── public/
│ └── markdown-editor.js
└── src/
└── MarkdownEditor.php
Composer
install via composer composer require cheinisch/markdown-editor
Usage
<?php require_once __DIR__ . '/src/MarkdownEditor.php'; ?> <!DOCTYPE html> <html lang="de"> <head> <?= MarkdownEditor::renderHead() ?> </head> <body> <?= MarkdownEditor::render() ?> <?= MarkdownEditor::renderFoot() ?> </body> </html>
if you using the composer version
<?php use cheinisch\MarkdownEditor\MarkdownEditor; ?> <!DOCTYPE html> <html lang="de"> <head> <?= MarkdownEditor::renderHead() ?> </head> <body> <?= MarkdownEditor::render() ?> <?= MarkdownEditor::renderFoot() ?> </body> </html>
render() Options
All options are optional.
<?= MarkdownEditor::render([ // Visible toolbar buttons. // Possible values: 'bold', 'italic', 'underline', 'h1', 'list', // 'quote', 'code', 'link', 'table', 'library' // Default: all buttons 'buttons' => ['bold', 'italic', 'h1', 'list', 'link', 'table', 'library'], // Auto-save content to localStorage. // true → key 'markdown-editor-content' // 'custom-key' → custom key 'localStorage' => 'my-editor', // Sync content with an existing <textarea> by ID. // If the element already exists in the DOM it will be used as-is. // If it doesn't exist, the editor creates a hidden one automatically. 'field' => 'post_content', // Directories for the image/file library modal. // path – URL endpoint (GET = list files, POST = upload). // Relative paths are resolved from the current PHP file. // upload – true: enables drag & drop and upload button. // recursive– true: includes subdirectories (?recursive=1). 'library' => [ [ 'name' => 'All Images', 'path' => '/api/media/images', ], [ 'name' => 'Blog', 'path' => '/api/media/blog', 'upload' => true, ], [ 'name' => 'Archive', 'path' => '/api/media/archive', 'recursive' => true, ], [ 'name' => 'Downloads', 'path' => '/api/media/downloads', 'upload' => true, 'recursive' => true, // Non-image files (PDF, DOCX …) are inserted as links: [name.pdf](…) // Image files are inserted as:  ], ], ]) ?>
Library API Endpoint
Use MarkdownEditor::handleRequest() to handle image listing and uploads in a single file.
// e.g. /api/media/blog.php <?php require_once __DIR__ . '/../../src/MarkdownEditor.php'; MarkdownEditor::handleRequest( fsDirectory: __DIR__ . '/../../storage/media/blog', webPath: '/storage/media/blog', options: [ // Allowed MIME types for upload 'types' => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], // File extensions shown in the library // Default: jpg, jpeg, png, gif, webp, avif, svg 'listExtensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp'], // Max upload size in bytes (default: PHP upload_max_filesize) // 'maxSize' => 5 * 1024 * 1024, ], );
GET /api/media/blog returns a JSON array:
[
{ "src": "/storage/media/blog/photo.jpg", "name": "photo.jpg", "width": 1280, "height": 720, "type": "image" }
]
POST /api/media/blog accepts a multipart/form-data request with a file field and returns the saved file as JSON.