Welcome to Milk Admin,
Revision: 2025/10/18
a ready-to-use admin panel written in PHP and designed to support the work of developers. It manages cron jobs, allows you to create public APIs, emails, manages users, permissions and CRUD.
Developed with a Bootstrap template and a lightweight and easy-to-learn framework for creating independent systems.
The system offers an excellent level of automatic protection from CSRF and SQL Injection, as well as extensive initial documentation.
Try it, the installation system is very fast and you can customize it for your needs. This way you can create your own webapp. Keeping it updated is even easier, you will only need, once you have finished making changes, a single shell command to create a new update version.
Key Concepts
Modules: The Building Blocks
MilkAdmin is organized around Modules - self-contained components that handle specific functionality. Each module can include:
- AbstractModule - The main class that configures the module (page name, menu, permissions, assets)
- AbstractController - Handles routing and actions (optional, for complex modules)
- AbstractModel - Manages database operations and schema definitions
- Views - Template files for rendering HTML
- Assets - CSS, JavaScript, and other resources
The module system follows the MVC pattern, keeping your code organized and maintainable. See Abstract Module for complete documentation.
Models: Your Database Layer
The Model system provides a powerful ORM-like interface for database operations:
- Schema Definition - Define tables using fluent syntax:
$rule->string('name')->required() - CRUD Operations - Built-in methods (examples):
save(),fill(),getEmpty(),store(),getById(),delete(),getAll()and many more - Query Builder - Chain conditions (examples):
where()->order()->limit()and many more - Relationships - Support for
hasOne(),hasMany(),belongsTo() - Validation - Automatic validation based on schema rules
Models handle table creation, updates, and migrations automatically. See Getting Started - Model for a complete tutorial.
Builders: Your Productivity Tools
MilkAdmin includes a set of Builder classes that speed up development by providing fluent, chainable interfaces for common tasks:
- FormBuilder - Create complete forms automatically from your Models with validation and actions
- TableBuilder - Generate dynamic tables with sorting, filtering, pagination, and custom columns
- LinksBuilder - Build navigation elements (navbar, breadcrumbs, sidebars, tabs) with automatic active state
- TitleBuilder - Create consistent page headers with titles, buttons, and search functionality
Builders replace verbose manual code with clean, readable method chains. For example, instead of manually creating form HTML and validation logic, you can use FormBuilder::create($model)->getForm() to get a complete working form instantly.
Install modules
First, you can try downloading new modules from the official repository https://www.milkadmin.org/download-modules/. Once downloaded, you can install it by uploading the module directly from the administrative interface in the "installation" section.
If you are creating a module and want to create or update the module tables, you can use
php milkadmin/cli.php module:install
php milkadmin/cli.php module:update
Create a Hello World module
Create a file milkadmin/Modules/HelloWorld/HelloWorldModule.php:
<?php
namespace Modules\HelloWorld;
use App\Abstracts\AbstractModule;
use App\Attributes\RequestAction;
use App\Response;
class HelloWorldModule extends AbstractModule {
protected function configure($rule): void
{
$rule->page('hello-world')
->title('Hello World')
->menu('Hello World', '', 'bi bi-bluesky', 10)
->access('registered');
}
#[RequestAction('home')]
public function helloWorld() {
Response::render('Hello World');
}
}
// ⚠️ DO NOT ADD THIS LINE IN REAL MODULES!
// This is only for standalone example modules
new HelloWorldModule();
Important: Module Initialization
DO NOT add new HelloWorldModule() in your real modules!
The framework automatically loads and initializes all modules. Manual initialization causes errors like:
- Duplicate menu entries
- Duplicate routes
- Performance issues
Only use new ModuleName() for:
- Standalone test modules (like this HelloWorld example)
- Modules that need to be loaded outside the standard flow
How does it work?
The configure() method uses a fluent interface to set up your module:
page('hello-world')- Sets the URL parameter (?page=hello-world)title('Hello World')- Sets the module titlemenu('Hello World', '', 'bi bi-bluesky', 10)- Creates a sidebar menu entry with an icon and orderaccess('registered')- Requires registered users (other options: 'public', 'authorized', 'admin')
RequestAction attributes define which methods handle which URLs:
#[RequestAction('home')]makes the method handle?page=hello-world(default action)- The
Responseclass renders the page content using the active theme
For example, if you wanted to create a second page:
#[RequestAction('second-page')]
public function myCustomSecondPage() {
Response::render('This is my second page');
}
This would handle the URL ?page=hello-world&action=second-page.
Learn More: See the complete guide at Creating Pages and Links in Modules to understand RequestAction, configure(), and how to structure complex modules.
System structure
Milk Admin
Contains the core, modules and template of the project.
Milk Admin/
├── milkadmin_local/ # Space dedicated to customization of the distributed system
├── app/ # The framework
├── modules/ # Here you find all the system code development
├── storage/ # Sqlite if used and other storage data
├── theme/ # All the graphics and html of the system
milkadmin_local
Contains the modifications for a specific installation. It contains configuration files, media files, and possibly module override files.
milkadmin_local/
├── config.php # System parameters
├── functions.php # Functions
├── storage/ # Storage data (sqlite, json, keys, etc.)
├── media/ # Media
public_html
Contains the site access files. The site must point to public_html/index.php and the API to public_html/api.php. This folder should not be modified in a normal project.
For WordPress lovers, inside milkadmin_local you will find functions.php which is the equivalent of functions.php in WordPress themes.