Skip to content

Admin - Modulární struktura

Petrovo CMS organizuje admin panel v app/admin/ jako modulární systém, kde každý modul obsahuje veškerý relevantní kód:

  • Controller (API třída)
  • Šablony
  • Konfiguraci
  • Helpery a utility

Toto sjednocuje rozptýlenou strukturu původního přístupu (Controllers/ADMIN, templates/ADMIN/listing, pages/ADMIN) do jednoho logického místa.

Přehled struktury

app/admin/
├── admin.php              # Dispatcher - načítá YAML a instanciuje controllery
├── login.php              # Auth handler - přihlášení
├── logout.php             # Auth handler - odhlášení
├── adminneo.php           # Wrapper pro AdminNeo nástroj
├── files.gallery.php      # Wrapper pro Files Gallery nástroj
├── modules/               # 20 modulů s modulární strukturou
│   ├── Admins/
│   ├── AdminsGroups/
│   ├── AdminsPermissions/
│   ├── Blocks/
│   ├── Categories/
│   ├── ... (celkem 20 modulů)
│   └── Superadmin/
├── shared/                # Sdílené utility
│   ├── SelectOptions/     # 18 tříd pro select/checkbox volby
│   └── Helpers/           # Paginator a další helpery
├── tags/                  # Admin-specifické šablonové tagy
│   ├── assets/
│   ├── cropit/
│   ├── cubes/
│   ├── menu/
│   ├── openai/
│   ├── translation/
│   └── upload/
└── templates/             # Sdílené šablony
    ├── admin.tpl          # Hlavní layout
    ├── login.tpl          # Login formulář
    ├── _assets.tpl        # Assets (CSS, JS)
    ├── _footer.tpl        # Footer
    ├── _metadata.tpl      # Meta tagy
    ├── _pagination.tpl    # Paginace
    └── _pagination_sum.tpl # Souhrn paginace

Modulární struktura

Každý modul (např. Blocks) má jednotnou strukturu:

app/admin/modules/Blocks/
├── BlocksApiController.php     # namespace Admin\Api\Blocks
├── BlocksHelper.php            # Skelet pro budoucí logiku
├── data.yaml                   # YAML konfigurace pro admin formulář
├── router.php                  # Skelet pro API routes
├── templates/
│   └── listing.tpl             # Hlavní šablona modulu
└── src/
    ├── js/
    │   └── blocks.js           # JavaScript pro modul
    └── scss/
        └── blocks.scss         # Styly pro modul

Namespace a třída

Každý modul má vlastní namespace:

// app/admin/modules/Blocks/BlocksApiController.php
namespace Admin\Api\Blocks;

class BlocksApiController extends \Main
{
    public function listing()
    {
        // Modul logika
    }
}

Namespace mapování v composer.json:

"psr-4": {
    "User\\Api\\": "app/admin/modules",
}

Soubor data.yaml

data.yaml definuje admin formulář deklarativně:

title: Bloky
# form_fields: definují admin UI pro CRUD operace
form_fields:
  - name: title
    type: text
    required: true
  - name: content
    type: textarea
  # ... další pole

Tento soubor je načten v app/admin/admin.php a zpracován třídu PageFields.

Dispatcher a routing

app/admin/admin.php

Hlavní dispatcher - načítá konfiguraci a instanciuje controllery na základě PAGE konstanty:

<?php
declare(strict_types=1);

use Petrovo\Yaml;

// Načti YAML z modulární cesty
$moduleName = ucfirst(PAGE);
$modulePath = dirname(__DIR__) . '/admin/modules/' . $moduleName . '/data';

$page = Yaml\load($modulePath) ?: [];

app/admin/tags/page_action.php

Dispatcher pro konkrétní akce (listing, new, edit, delete):

<?php
// Načti modularní controller
$moduleName = ucfirst(PAGE);
$controller = 'User\\Api\\' . $moduleName . '\\' . $moduleName . 'ApiController';

if (class_exists($controller)) {
    $page = new $controller();
    if (method_exists($page, $action)) {
        $page->{$action}();
    }
}

Všechny moduly jsou nyní v namespace Admin\Api\{Module} - žádný fallback na starý systém.

Šablonování - ADMIN/ prefix

Template engine automaticky routuje tagy s ADMIN/ prefixem do app/admin/tags/:

// core/Template/BaseTemplate.php - phpTag() metoda

if (str_starts_with($elementName, 'ADMIN/')) {
    $tagName = substr($elementName, 6);  // 'menu/menu'
    $handle = DIR . '/app/admin/tags/' . $tagName . '.php';
} else {
    $handle = DIR . '/app/tags/' . $elementName . '.php';  // Frontend tag
}

Příklady:

  • {T ADMIN/menu/menu}app/admin/tags/menu/menu.php
  • {T footer}app/tags/footer.php

20 modulů

Modul Controller Popis
Admins AdminsApiController Správa admin uživatelů
AdminsGroups AdminsGroupsApiController Skupiny oprávnění
AdminsPermissions AdminsPermissionsApiController Jednotlivá oprávnění
Blocks BlocksApiController Statické bloky obsahu
Categories CategoriesApiController Kategorie článků
CookieBar CookieBarApiController Cookies consent bar
Cubes CubesApiController Správa cube typů
CubesUse CubesUseApiController Instance cubů v obsahu
I18n I18nApiController Překlady
LogForms LogFormsApiController Logy formulářů
Menus MenusApiController Navigační menu
MenusNodes MenusNodesApiController Položky menu
News NewsApiController Články/novinky
Newsletter NewsletterApiController Newsletter manažer
Pages PagesApiController Stránky webu
Photogalleries PhotogalleriesApiController Fotogalerie (skupiny)
Photogallery PhotogalleryApiController Fotografie v galerii
Redirection RedirectionApiController Přesměrování URL
Setting SettingApiController Globální nastavení
Superadmin SuperadminApiController Super-admin funkce

Admin Tagy

Admin-specifické tagy v app/admin/tags/:

app/admin/tags/
├── assets/          # CSS/JS assets loader
├── cropit/          # CropIT - editace obrázků
├── cubes/           # Cube management UI
├── menu/            # Menu builder
├── openai/          # OpenAI integration
├── translation/     # Překlad obsahu
├── upload/          # Upload a image management
└── page_action.php  # Dispatcher (viz výše)

Tyto tagy jsou přístupné pouze v admin šablonách (označené {T ADMIN/...}).

Přidání nového modulu

Manuálně (bez scriptu)

  1. Vytvoř složku a strukturu:
mkdir -p app/admin/modules/MyModule/templates app/admin/modules/MyModule/src/{js,scss}
  1. Vytvoř controller:
<?php
// app/admin/modules/MyModule/MyModuleApiController.php
declare(strict_types=1);

namespace Admin\Api\MyModule;

class MyModuleApiController extends \Main
{
    public function listing()
    {
        // Tvá logika
    }
}
  1. Vytvoř šablonu:
<!-- app/admin/modules/MyModule/templates/listing.tpl -->
{T ADMIN/page_action action="listing"}
{+ @admin/_pagination}
  1. Vytvoř konfiguraci:
# app/admin/modules/MyModule/data.yaml
title: Můj modul
form_fields:
  - name: name
    type: text
  1. Vytvoř skeletty:
// app/admin/modules/MyModule/MyModuleHelper.php
<?php
declare(strict_types=1);

namespace Admin\Api\MyModule;

class MyModuleHelper
{
}
// app/admin/modules/MyModule/routes.php
<?php
declare(strict_types=1);

/**
 * Router for MyModule API
 * Load automatically from app/routes/app-admin-api.php
 */

Migrace - hotovo

Všechny 20 modulů jsou migrovány na nový systém - fallback logika byla odstraněna:

Nový systém (modulární)

  • app/admin/modules/{Module}/{Module}ApiController.php (namespace Admin\Api\{Module})
  • app/admin/modules/{Module}/templates/listing.tpl
  • app/admin/modules/{Module}/data.yaml

Legacy adresáře (app/Controllers/ADMIN/, app/pages/ADMIN/, app/templates/ADMIN/listing/) zůstávají, ale již nejsou používány.

Filozofie - Determinismus

Admin panel design sleduje Petrovo filosofii:

Transparentnost - Controller je viditelný, co se stane je zřejmé

Bez magie - Žádné autoinject, žádné event handling, žádné lazy loading

Čitelnost - Malý tým ví o všech modulech a může číst kterýkoli

Modularita - Každý modul je samostatný, bez skrytých závislostí

Admin panel není API pro "nezávislý frontend" - je to spřažený admin systém se sdílením šablon, tagů a helperů.

Routing změny v app/bootstrap.php

Admin panel je routován přes app/routes/app-admin.php (dříve app-backend.php):

// app/bootstrap.php
elseif (str_starts_with($requestPath, '/ADMIN')) {
    $response = require 'routes/app-admin.php';  // Nový název
} elseif (str_starts_with($requestPath, '/ADMIN/api')) {
    $response = require 'routes/app-admin-api.php';  // Nový název
}

Tyto soubory registrují middleware pipeline a routes pro admin panel.

Viz také