adaiasmagdiel / erlenmeyer-starter
Starter template for web applications with Erlenmeyer and related packages
Package info
github.com/AdaiasMagdiel/erlenmeyer-starter
Type:project
pkg:composer/adaiasmagdiel/erlenmeyer-starter
Requires
- php: ^8.1
- adaiasmagdiel/erlenmeyer: ^5.0
- adaiasmagdiel/fullcrawl: ^1.2
- vlucas/phpdotenv: ^5.6
README
A starter template for adaiasmagdiel/erlenmeyer with batteries included: Vue 3, Tailwind CSS, Sonner.js, FullCrawl migrations, and phpdotenv.
Stack
| Layer | Tech |
|---|---|
| Framework | Erlenmeyer v5 |
| Migrations | FullCrawl v1.2 |
| Env vars | vlucas/phpdotenv v5 |
| Frontend | Vue 3 (CDN) |
| Styling | Tailwind CSS v3 (CDN) |
| Toasts | Sonner.js (CDN) |
Requirements
- PHP ^8.1 with
jsonandmbstringextensions - Composer
- Apache with
mod_rewriteenabled - MySQL / MariaDB (or PostgreSQL / SQLite)
Getting Started
# 1. Clone the repo git clone https://github.com/adaiasmagdiel/erlenmeyer-starter.git cd erlenmeyer-starter # 2. Install dependencies composer install # 3. Configure environment cp .env.example .env # Edit .env with your database credentials # 4. Run migrations (if any) php fullcrawl.php # 5. Serve php -S localhost:8000
For production, point your Apache virtual host to the project root.
mod_rewritemust be enabled — all requests are routed throughindex.php.
Project Structure
erlenmeyer-starter/
├── app/
│ ├── Controllers/
│ │ └── Site.php # Example controller
│ ├── Database.php # PDO wrapper (singleton)
│ └── helpers.php # t(), e(), isDev(), genv()
├── templates/
│ ├── layouts/
│ │ └── dashboard.php # Main HTML layout
│ ├── dashboard/
│ │ └── index.php # Example page with Vue component
│ ├── site/
│ │ └── index.php # Welcome page
│ ├── 404.php
│ └── 500.php
├── bootstrap.php # Env & DB initialization
├── index.php # Entry point & routes
├── fullcrawl.php # Migration config
├── .env.example
└── .htaccess
Adding Routes
Routes are defined in index.php:
$app->get('/', [Site::class, 'index']); $app->post('/users', [Users::class, 'store']);
Creating Pages
Pages use output buffering to separate body and script from the layout:
<?php ob_start(); ?> <template id="tpl-page"> <main> <p>Hello, {{ store.user.name }}</p> </main> </template> <?php $body = ob_get_clean(); ?> <?php ob_start(); ?> <script> window.__APP.component('page', { template: '#tpl-page', setup() { const store = Vue.inject('store'); return { store }; } }); </script> <?php $script = ob_get_clean(); ?> <?php $page = ['body' => $body, 'script' => $script, 'info' => ['title' => 'My Page']]; include t('layouts/dashboard');
Global State
A reactive Vue store is available via inject('store') in any component:
// provided in layouts/dashboard.php const store = Vue.reactive({ user: { name: '...', role: '...' } }); __APP.provide('store', store);
Helpers
| Helper | Description |
|---|---|
t(string $path) |
Resolves a template path to absolute path |
e(?string $value) |
HTML-escapes a string (XSS prevention) |
isDev(): bool |
Returns true when ENV=development |
genv(string $key, mixed $default) |
Gets an environment variable |
Database
Configure credentials in .env. The Database class wraps PDO:
$pdo = Database::getConn(string $key = 'default'); // returns the PDO connection
Supports MySQL, MariaDB, PostgreSQL, and SQLite.
License
GPL v3 — see LICENSE for details.