blackcube / starter
Blackcube CMS starter
Requires
- php: ^8.1
- ext-json: *
- blackcube/dboard: ^1.0
- blackcube/dcore: ^1.0
- blackcube/graphql: ^1.0
- blackcube/ssr: ^1.0
- blackcube/yii-assets: ^1.0
- blackcube/yii-proxy-middleware: ^1.0
- httpsoft/http-message: ^1.1
- vlucas/phpdotenv: ^5.6
- yiisoft/aliases: ^3.1
- yiisoft/cache-redis: ^2.0
- yiisoft/config: ^1.6
- yiisoft/data: ^2.0
- yiisoft/data-response: ^2.2
- yiisoft/db: ^2.0
- yiisoft/db-migration: ^2.0
- yiisoft/db-mysql: ^2.0
- yiisoft/definitions: ^3.4
- yiisoft/di: ^1.4
- yiisoft/error-handler: ^4.3
- yiisoft/event-dispatcher: ^1.1
- yiisoft/factory: ^1.3
- yiisoft/input-http: ^1.0
- yiisoft/log: ^2.2
- yiisoft/log-target-file: ^3.1
- yiisoft/rbac-db: ^2.1
- yiisoft/router: ^4.0
- yiisoft/router-fastroute: ^4.0
- yiisoft/test-support: ^3.2
- yiisoft/yii-console: ^2.4
- yiisoft/yii-http: ^1.1
- yiisoft/yii-runner-console: ^2.2
- yiisoft/yii-runner-http: ^3.2
- yiisoft/yii-view-renderer: ^7.4
This package is auto-updated.
Last update: 2026-05-04 18:01:19 UTC
README
Demonstration application for Blackcube CMS on Yii3. Use as a starting point with composer create-project.
Requirements
- PHP 8.4+
- MySQL / MariaDB
- Composer
- Node.js (for frontend assets)
Installation
composer create-project blackcube/starter my-project
cd my-project
cp .env.example .env
Create oauth2 keys:
# private key (2048 bits minimum, 4096 recommanded) openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:4096 # public key openssl rsa -in private.pem -pubout -out public.pem
and copy the keys in config/keys/
Edit .env with your database credentials:
DB_DRIVER=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=myapp DB_USER=myapp DB_PASSWORD=myapp
and all needed conf vars
Run the migrations:
php yii.php migrate:up
Stack
- blackcube/dcore — data layer (entities, slugs, SEO)
- blackcube/dboard — administration panel
- blackcube/ssr — server-side routing and rendering
Configuration
Parameters — config/common/params.php
'blackcube/ssr' => [ 'scanAttributes' => true, 'scanAliases' => ['@src/Handlers'], ],
| Parameter | Description |
|---|---|
scanAttributes |
Scan handler classes for #[RoutingHandler] attributes |
scanAliases |
Yii aliases pointing to directories containing handlers |
Middleware — config/web/di/application.php
SsrRoutingMiddlewareInterface::class => YiiSsrRoutingMiddleware::class,
static function (SsrRoutingMiddlewareInterface $middleware) use ($params): SsrRoutingMiddlewareInterface { return $middleware // ->withExcludedPrefixes('dboard/', 'api/graphql') ->withXeo() ->withMdAlternate(); },
Pipeline order:
ErrorCatcher → Session → CookieLogin → CSRF → SsrRoutingMiddleware → Router
Handlers
A handler renders CMS content. The SSR middleware resolves the handler via the Type's handler field: a Type with handler: 'article' dispatches to the class carrying #[RoutingHandler(route: 'article')].
Place handler classes in src/Handlers/:
#[RoutingHandler(route: 'landing')] final class LandingHandler implements RequestHandlerInterface { public function __construct( private readonly Content|Tag $element, private readonly WebViewRenderer $viewRenderer, ) {} public function handle(ServerRequestInterface $request): ResponseInterface { // $this->element is the Content or Tag resolved from the slug // $this->viewRenderer carries Xeo injections (meta, OG, JSON-LD) } }
The CMS entity and Yii services are injected in the constructor. The request is passed to handle().
Error handlers
#[RoutingHandler(route: 'not-found', errorCode: 404)] final class NotFoundHandler implements RequestHandlerInterface { } #[RoutingHandler(route: 'server-error', errorCodesRange: [500, 599])] final class ServerErrorHandler implements RequestHandlerInterface { }
Special routes
Handled automatically by the SSR package — no code needed:
| Route | Content-Type | Source |
|---|---|---|
/sitemap.xml |
application/xml |
Active CMS slugs with sitemap metadata |
/robots.txt |
text/plain |
GlobalXeo "Robots" entry |
/llms.txt |
text/plain |
LlmMenu navigation tree |
/llms-full.txt |
text/plain |
LlmMenu tree with full markdown content |
/{slug}.md |
text/markdown |
Markdown export of any CMS page |
| Redirects | 301/302 | Slugs with a target URL |
License
BSD-3-Clause. See LICENSE.md.
Author
Philippe Gaultier philippe@blackcube.io