New "VITEC Import" module under Web: one import page per domain model (v1: Market, Solution, Product - registry-driven, adding a model is one config entry). Workflow: upload a CSV (delimiter and encoding are auto-detected, including German-Excel semicolon/Windows-1252), map CSV columns to DB fields, persist the mapping per model together with the identity field used for matching (new table tx_vitec_import_mapping, no TCA - pure tool configuration), review a unified list of CSV rows matched against the DB records (new / update with differing fields / unchanged / db-only), then apply the checked rows through DataHandler. Each importable row carries an editable JSON payload textarea - what is written is the textarea content, not the raw CSV, so editors can fix values right in the review step. The parsed CSV travels through the form as a hidden JSON field: no session state, no temp files. Importable fields are derived from TCA at runtime (scalar types only; files, categories and other relations are excluded - a flat CSV cannot carry them). Payloads are whitelisted against that field list on apply; new records require a storage pid (prefilled from existing records). BE user permissions apply via DataHandler. The module ships its own CSS (backend-import.css, loaded only by this module) using the frontend button palette from _vitec.scss: orange #f47937 for primary actions, navy #26358c for secondary actions and structure. The stray <h2>Hi</h2> debug leftover in the shared backend layout is removed (also affects the OG Image module). A fourth tab "SEO Research" handles the recurring keyword-research CSV. It is deliberately not an import mask - the file carries research only (no meta title/description yet). Each upload is persisted as a delivery (tx_vitec_seo_research, never deleted) and evaluated: diff against the previous delivery keyed by URL, a structure check of the CSV tree against TYPO3 (pages by slug path; market/solution/product rows against the domain tables, matched by slug then normalized title), and the three work lists from the SEO flags (quick wins by GSC impressions, shared terms grouped by keyword, already ranking). CsvReader now deduplicates repeated header names, which that CSV has. New CLI command vitec:create-markets: creates the market records the structure check reports as missing, sourced from the stored delivery and matched through the same SeoResearchService - what the module lists is what the command creates. Each market gets a sys_category of the same title, found anywhere under the auto-detected market category root or created; sub-market categories are created under the parent market's category, so the category tree carries the hierarchy the flat market model cannot. Idempotent, dry-run first. New CLI commands vitec:create-markets and vitec:market-dummy-image. create-markets creates the market records the structure check reports as missing (root detection three-staged: option, auto-detect, find or create a "Markets" category). market-dummy-image assigns a shared placeholder (white logo on brand navy, fileadmin/placeholders/) to every market without an image - one sys_file for all, replacing the file restyles every placeholder at once. Both idempotent. Deliberately out of v1: import log with three-way compare (protection against overwriting manual edits), images/relations, multiple saved mappings per model.
VITEC Platform
Headless TYPO3 v14 + React — the VITEC website
TYPO3 runs the editorial backend and serves content as JSON; a decoupled React front end renders it. This repository is the TYPO3 Composer distribution.
Overview This is a TYPO3 CMS base distribution configured for headless operation. Editors work in the TYPO3 backend; every page is exposed as a JSON document (no server‑side HTML). The compiled React application in
public/_frontend/consumes that JSON. All custom domain logic — content elements, plugins, layout containers and the JSON renderers — lives in theevomedien/vitecextension.
Table of contents
- How it fits together
- Tech stack
- Repository layout
- Requirements
- Getting started
- Configuration
- Everyday commands
- Deployment notes
- Documentation
- License
How it fits together
┌────────────┐ edits ┌─────────────────────┐ JSON per page ┌────────────────┐
│ Editors │ ─────────────▶ │ TYPO3 v14 backend │ ────────────────▶ │ React (Vite) │
│ (backend) │ │ headless: 1 │ /page → { … } │ public/_front │
└────────────┘ └─────────────────────┘ └────────────────┘
│
▼
evomedien/vitec extension
(content elements · plugins · JSON-LD)
The heavy lifting — the JSON envelope, per‑plugin renderers, layout containers and
schema.org structured data — is documented in the extension’s architecture spec:
packages/vitec/Documentation/Headless-JSON-Architecture.md.
Tech stack
| Layer | Technology |
|---|---|
| CMS / backend | TYPO3 CMS ^14.3 (headless) |
| Language / runtime | PHP 8.4 |
| Dependency management | Composer (base distribution) |
| Headless rendering | friendsoftypo3/headless, nb-headless-content-blocks |
| Content modelling | friendsoftypo3/content-blocks, b13/container |
| News | georgringer/news |
| Custom logic | evomedien/vitec (see packages/vitec/) |
| Front end | React, built with Vite → public/_frontend/ |
Repository layout
live/
├── config/
│ ├── sites/vitec/config.yaml # site config (headless: 1, Sets, routing)
│ └── system/settings.php # TYPO3 system config (git-ignored — secrets)
├── packages/
│ └── vitec/ # the custom extension (see its own README)
├── public/
│ ├── index.php # TYPO3 front controller
│ ├── _frontend/ # compiled React app (Vite build)
│ ├── _assets/ # published extension assets
│ ├── fileadmin/ typo3/ …
├── var/ # caches, logs (git-ignored)
├── vendor/ # Composer dependencies (git-ignored)
├── Documentation/ # project-level docs
├── composer.json / composer.lock
├── auth.json # Composer auth for private repos (git-ignored)
└── fix-asset-perms.sh # deploy helper — fixes asset file permissions
Requirements
- PHP 8.4
- Composer 2
- MySQL / MariaDB (database)
- Node.js (only to build the front end)
- Access to the private
t3planetComposer repository (viaauth.json)
Getting started
# 1. Install PHP dependencies (requires a valid auth.json for the private repo)
composer install
# 2. Configure the system (database, encryption key, …)
# config/system/settings.php is git-ignored; create it via the Install Tool
# or copy it from a secure source.
# 3. Apply the database schema
vendor/bin/typo3 database:updateschema "*.add,*.change"
# 4. Warm up
vendor/bin/typo3 cache:flush
The document root is public/. Point the web server there; public/index.php is
the TYPO3 entry point.
Configuration
- Headless mode & routing —
config/sites/vitec/config.yaml:base: / headless: 1 dependencies: - friendsoftypo3/headless - friendsoftypo3/headless-mixed - nb-headless-content-blocks/headless-content-blocks - georgringer/news - System settings & secrets —
config/system/settings.phpandauth.jsonare git-ignored. Never commit database credentials or Composer tokens.
Everyday commands
vendor/bin/typo3 cache:flush # clear all caches
vendor/bin/typo3 database:updateschema "*.add,*.change" # apply schema changes
bash fix-asset-perms.sh # fix asset permissions (see below)
Deployment notes
- Document root:
public/. - Asset permissions: when files are deployed over an SSHFS/Windows mount they can
land with a too‑restrictive mode (no “other” read), which makes the web server return
403 for backend icons/CSS/JS. Run
fix-asset-perms.shon the server after deploying assets (it sets files to644/ directories to755underpublic/_assetsand the extension’sResources/Public, then flushes caches). - Never commit
config/system/settings.phporauth.json(already git-ignored).
Documentation
| Document | Purpose |
|---|---|
packages/vitec/README.md |
The custom extension — features & content elements |
packages/vitec/Documentation/Headless-JSON-Architecture.md |
Authoritative headless architecture & JSON interface spec |
Documentation/CustomFrameClasses.md |
Custom frame classes |
VITEC-ContentBlocks-Setup.md |
Content Blocks setup notes |
License
GPL‑2.0‑or‑later — © evomedien.
vitecdev 17ZJfy75sJoU68J6