📊 Documentation & Quality Dashboard — guide, project docs, CI metrics
This is a modernized version of Pagekit CMS, extensively updated for contemporary web development practices. The system has been thoroughly upgraded to support the latest PHP versions, modern frameworks, and improved development workflows.
- Modern PHP Support: PHP 8.5+ compatibility with modern coding standards
- Enterprise Security: Zero vulnerabilities with latest security patches applied
- Advanced Frontend: Vue.js 2.7 with UIkit 3.5 for responsive, modern interfaces
- Flexible Database: Support for both MySQL 8.4 and SQLite 3 with Doctrine DBAL 3.8+
- Modern Logging: Monolog 3.9+ with enhanced performance and debugging capabilities
- Secure Dependencies: Latest security patches applied (marked 4.3+, doctrine/annotations 2.0+)
- Developer-Friendly: Docker development stack with the working tree bind-mounted and an asset watcher
- Built-in Extensions: Blog, Admin Theme, Theme One, and Demo Content included
- Mobile-Optimized: Responsive design across all devices
- Blog Extension: Full-featured blogging system
- Admin Theme: Modern UIkit 3 based administration interface
- Theme One: Responsive frontend theme
- Demo Content: Sample data for quick setup
- PHP Version: Minimum PHP 8.5+
- Database Support: MySQL 8.4+ and SQLite 3
- Node.js: Minimum Node 20.19+ or 22.12+ (Node 22 LTS recommended) for development
- Composer: Version 2.0+ required
- pnpm: Version pinned in
package.json(packageManager), activated via Corepack - Framework Updates: Symfony 6.4 LTS components with modern architecture
- PSR Standards: Native PSR-11 Container with constructor dependency injection
- Security Updates: All dependencies updated to secure versions (0 vulnerabilities confirmed)
- Database Layer: Doctrine DBAL 3.8+ with modern query methods and enhanced compatibility
- Logging System: Monolog 3.9+ with improved performance and PHP 8.5 support
- Frontend Modernization: Vue.js 2.7 and UIkit 3.5 (jQuery completely removed)
- Build Tools: pnpm workspace with Vite bundling and Node-based LESS/asset scripts
- Extension Compatibility: Legacy extensions and themes require complete rewrite for new system
- Docker Support: Complete containerized development environment
Important Note: Original Pagekit extensions and themes are not compatible with this modernized version and must be completely rewritten to work with the new architecture.
- PHP: 8.5 or higher
- MySQL: 8.4+ or SQLite: 3.x (selectable during installation)
- Node.js:
^20.19.0 || >=22.12.0(Node 22 LTS recommended; pinned via.nvmrcandpackage.jsonengines) - Composer: 2.0+
- pnpm: version pinned in
package.json(packageManager). Enable it withcorepack enable, or install it globally withnpm install -g pnpmif Corepack is unavailable. Installs run through any other package manager are rejected by apreinstallguard.
- Docker: Recent version with Compose v2 (
docker compose) - Git: For version control
- Modern Browser: Chrome, Firefox, Safari, Edge
-
Clone the repository
git clone https://github.com/Shadesman5/pagekit.git cd pagekit -
Generate the environment file
# Windows (PowerShell) .\docker-setup.ps1 # Linux/Mac chmod +x docker-setup.sh ./docker-setup.sh
The script copies
.env.exampleto.envand replaces both MySQL passwords with generated values..envis gitignored, and Compose reads it automatically. -
Start the stack
# With MySQL (default): web, mysql, phpmyadmin and the node watcher docker compose up -d # Without a database server (SQLite path): web and node only docker compose up -d --no-deps web node
--no-depsskips the MySQL dependency of thewebservice, so no database container is started. -
Install the PHP dependencies in the container
docker compose exec web composer installThe image contains PHP, Apache and Composer only — the project itself is bind-mounted. The
nodeservice installs its own dependencies, builds the frontend assets and then starts the watcher when it comes up. -
Install Pagekit
-
MySQL path: open http://localhost:8080 and complete the web installer. Database host is
mysql, port3306; database name, user and password are theMYSQL_*values from your.env. -
SQLite path: install from the command line, no database server involved:
docker compose exec web php pagekit setup -u admin -p '<password>' \ -t "Pagekit Dev" -m admin@example.com -d sqlite --no-interaction
-
-
Access the application
- Website: http://localhost:8080
- Admin Panel: http://localhost:8080/admin
- phpMyAdmin: http://localhost:8081 (MySQL path only, signed in as the MySQL root user)
-
Install PHP dependencies
composer install
-
Install Node.js dependencies
corepack enable pnpm install -
Build frontend assets
pnpm build
The build fills
public/, the document root: JavaScript bundles, stylesheets, copied vendor assets and the link to the media library. A fresh checkout has nothing to serve until this has run. -
Set up web server
Point the document root at the
public/directory. Sources, configuration,tmp/and the media library itself stay outside it and are never reachable over HTTP.- Apache:
DocumentRoot /path/to/pagekit/public, withAllowOverride All(the shippedpublic/.htaccesscarries the rewrite rules and security headers),Options FollowSymLinks(the media library is a symlink) andmod_rewriteenabled - Nginx:
root /path/to/pagekit/public;and route unknown paths to the front controller:try_files $uri /index.php$is_args$args;— also deny*.db(e.g.location ~* \.db$ { deny all; }) since.htaccessdoes not apply. - Permissions:
tmp/andstorage/must be writable by the web server user
Shared hosting with a fixed document root: leave it on the project directory. The root
.htaccessrewrites every request intopublic/, so files beside it —config.php,app/,tmp/— resolve to nothing there and end up on the 404 page. This needsmod_rewriteandAllowOverride All, and it is the fallback: a document root onpublic/is the safer setup.Media library link: uploads are stored in
storage/and reach the browser throughpublic/storage.pnpm buildand the installer create that link; on hosts wheresymlink()is disabled they report the problem and leave it to be created by hand:ln -s ../storage public/storage
A media library moved elsewhere (Settings → System → Storage) needs its own link under the same relative path — a storage directory of
/mediais served frompublic/media, soln -s ../media public/media. Directories outside the project cannot be linked and need a web server alias instead. - Apache:
-
Install Pagekit
Open the site and complete the web installer, or install from the command line:
php pagekit setup -u admin -p '<password>' \ -t "Pagekit" -m admin@example.com -d sqlite --no-interaction
Without a web server, PHP's built-in server is enough for local use:
php pagekit start # http://127.0.0.1:8080 php pagekit start -s 0.0.0.0:9000 # bind elsewhere
It wraps
php -S <server> -t public public/index.phpand has to run from the project root.
The Docker setup provides a complete development environment with:
- PHP 8.5 with Apache (
mod_rewrite) and Composer. On top of the base image the build addspdo_mysql,gdandzip;pdo_sqlite,mbstringand the XML extensions are already bundled - MySQL 8.4 with phpMyAdmin —
webandphpmyadminstart only once the MySQL healthcheck passes - Node.js 22 LTS with pnpm (via Corepack) running
pnpm buildonce and thenpnpm watch - Live source: the working tree is mounted into both containers, so PHP edits take effect immediately and asset changes are rebuilt by the watcher
Watch mode for development:
# JavaScript/Vue bundles and LESS stylesheets
pnpm watchProduction builds:
# Everything the webroot needs: bundles, stylesheets, asset copies
pnpm build
# Or the individual parts
pnpm build:js
pnpm build:css
pnpm build:assetsCode quality:
# ESLint checking
pnpm lint
# ESLint with auto-fixing
pnpm lint --fix
# Formatting (check / write)
pnpm exec prettier --check .
pnpm exec prettier --write .Docker:
- Host:
mysqlfrom inside the stack,localhost:3306from the host - Database / Username:
MYSQL_DATABASE/MYSQL_USERfrom.env(both default topagekit) - Password:
MYSQL_PASSWORDfrom.env, generated by the setup script — there is no fixed default - The MySQL image creates the database, the user and its grants on the first boot of an empty data volume
Manual Setup:
- Create a MySQL database or use SQLite
- Configure database settings during web-based installation
- Framework: Symfony 6.4 LTS components
- Architecture: Modular system with clean separation of concerns
- Database: Doctrine ORM with migration support
- Authentication: User management and permission system
- JavaScript Framework: Vue.js 2.7 with modern component patterns
- CSS Framework: UIkit 3.5 for responsive design
- Build Tools: Vite per-module bundles with optimized production builds
- Code Quality: ESLint with Vue.js specific rules, Prettier for formatting
The admin interface has been completely modernized:
- UIkit 3 integration throughout
- Responsive design for all screen sizes
- Modern iconography with UIkit icons
- Improved UX with better navigation and workflows
- Enhanced menu system with dropdowns and better organization
The theme system allows programmatic configuration of buttons, dropdowns, pagination and search forms. Each page gets an auto-generated class in the body tag for individual styling.
Example: Dashboard Component (index.js)
name: 'dashboard',
mixins: [Theme.Mixins.Helper],
theme: {
hideEls: '#dashboard > div:first-child > div:last-child',
elements() {
var vm = this;
return {
addwidget: {
scope: 'topmenu-left',
type: 'dropdown',
caption: 'Add Widget',
class: 'uk-button uk-button-text',
icon: { attrs: { 'uk-icon': 'triangle-down' }},
dropdown: { options: () => 'mode: click' },
items: () => vm.getTypes().map((type) => {
let props = {
on: {click: () => vm.add(type)},
caption: type.label,
class: 'uk-dropdown-close'
}
return {...type, ...props}
}),
}
}
}
}Adding sidebar menu items via PHP:
'view.data' => function ($event, $data) use ($app) {
if (!$app->isAdmin()) {
return;
}
$data->add('Theme', [
'SidebarItems' => [
'additem' => [
'addpost' => [
'caption' => 'Add Post',
'attrs' => [
'href' => $app->get('url')->get('admin/blog/post/edit')
],
'priority' => 1
]
]
]
]);
}Multiple editor choices available in system settings:
- HTML Editor: Simple WYSIWYG editing
- TinyMCE: Advanced rich text editor with split-view mode
- CodeMirror: Syntax-highlighted code editor for developers
# Development
php pagekit start # Built-in PHP server, document root public/
pnpm watch # Watch JS/Vue and LESS files
# Production
pnpm build # Fill public/ with bundles, stylesheets and assets
pnpm build:js # Build JavaScript bundles only
pnpm build:css # Build CSS from LESS only
pnpm build:assets # Copy static assets and link the media library
# Testing
## Unit Tests
./app/vendor/bin/phpunit # Run PHPUnit test suite (275 tests)
./app/vendor/bin/phpunit --testdox # Run tests with detailed output
./app/vendor/bin/phpunit --coverage-html coverage/ # Generate code coverage
## E2E Tests
pnpm test:e2e # Run all E2E tests
pnpm test:e2e:headed # Run tests with browser visible
pnpm test:e2e:debug # Debug mode for test development
pnpm test:e2e:ui # Interactive UI mode
pnpm test:smoke # Run the @ci-tagged smoke specs
# Utilities
pnpm lint # Check code quality
pnpm exec prettier --check . # Check formatting
pnpm cldr # Update locale data# Container management
docker compose up -d # Start all services
docker compose up -d --no-deps web node # Start without MySQL (SQLite path)
docker compose ps # Show container status
docker compose down # Stop all services
docker compose down -v # Stop and remove volumes (deletes the MySQL data)
# Development
docker compose logs -f web # View web server logs
docker compose exec web bash # Access PHP container
docker compose exec node sh # Access Node.js container
# Dependencies
docker compose exec web composer install # Install PHP dependencies
docker compose exec node pnpm install # Install Node dependencies
# Frontend production build inside the container
docker compose exec node pnpm buildCompose aborts with Run ./docker-setup.sh first: the MySQL passwords come from .env. Run the setup script before starting the stack.
Port already in use: change the host side of the port mapping in docker-compose.yml, for example "8090:80" instead of "8080:80" on the web service.
Permission errors on written files (cache, storage, uploads):
docker compose exec web chown -R www-data:www-data /var/www/htmlImportant: The original Pagekit marketplace is no longer functional as the API was deactivated. This modernized version currently includes:
- Built-in Blog Extension: Full-featured blogging system
- Modern Admin Theme: UIkit 3 based administration interface
- Theme One: Responsive frontend theme
- Demo Content: Sample data for testing
- E2E Testing: Comprehensive Playwright-based testing framework
- Complete Rewrite Required: Original Pagekit extensions and themes do not work with this modernized system
- Modern Architecture: Extensions must be built from scratch using current PHP 8.5+ standards
- Theme System: Full theming support with modern tooling and developer APIs
- Hooks & Filters: Extensive customization capabilities for developers
Note: A new marketplace system needs to be developed from the ground up to replace the original functionality.
-
Never commit environment files:
.envholds the generated database passwords. The*.envrule in.gitignorekeeps it out of version control. -
Use the setup scripts: Always use the provided setup scripts (
docker-setup.ps1for Windows ordocker-setup.shfor Linux/Mac) to generate secure passwords automatically. No credentials are hardcoded in any tracked file. -
Development only: the image,
docker-compose.yml,.env.exampleanddocker/php/php.iniare development artefacts — errors are displayed, MySQL is published onlocalhost:3306and the working tree is mounted into the container. Do not deploy them; a production image ships with its own configuration and secret handling. -
Regular updates: Keep all Docker images and dependencies up to date for security patches.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Follow PSR coding standards
- Include tests for new functionality
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
This modernized version builds upon the work of many contributors:
- YOOtheme: Original creators of Pagekit CMS
- @uatrend: Major modernization efforts with UIkit 3, Vue.js 2, and PHP 7.4+ support
- @cssailing: Version updates, dependency management, and system improvements
- Vue.js, Symfony, and UIkit teams for their excellent frameworks
- Community contributors: All developers who have contributed to the modernization efforts
Special Thanks: This project exists thanks to the foundational work by @uatrend and @cssailing, which made seamless continuation and further development possible.
- Documentation: Currently being rewritten for the modernized system. For legacy reference, see the original Pagekit Documentation
- Issues: Report bugs via GitHub Issues
- Discussions: Use GitHub Discussions for questions and feature requests
Note: This is a fully modernized version. Original Pagekit extensions and themes are not compatible and must be rewritten for the new architecture.