oliverkroener / ok-ai-writer
AI Text Generator for CKEditor in TYPO3 - Azure OpenAI integration
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:JavaScript
Type:typo3-cms-extension
pkg:composer/oliverkroener/ok-ai-writer
Requires
- php: >=8.1
- typo3/cms-core: ^12.4 || ^13 || ^14
- typo3/cms-rte-ckeditor: ^12.4 || ^13 || ^14
This package is auto-updated.
Last update: 2026-02-15 01:13:37 UTC
README
TYPO3 extension that adds CKEditor 5 toolbar buttons for AI text generation, AI translation, and Lorem Ipsum insertion. Supports both Azure OpenAI and OpenAI (ChatGPT) APIs with per-site configuration and encrypted credential storage.
Features
AI Text Generator
- Adds a sparkle icon button to the CKEditor toolbar
- Opens a chat-style dialog with prompt input and text preview
- Generates HTML content via Azure OpenAI or OpenAI (ChatGPT) chat completions API
- Supports iterative refinement through conversation history
- Previews the generated text before inserting into the editor
- Token usage tracking per session
- Keyboard shortcuts: Enter to generate, Shift+Enter for new line, Escape to close
AI Translate
- Adds a globe icon button to the CKEditor toolbar
- Translates the entire editor content into a selected target language
- Supports 7 languages: Deutsch, English (US), English (UK), Espanol, Francais, Italiano, Turkce
- Preserves all HTML structure, tags, and attributes during translation
- Auto-replaces editor content on successful translation
- Shares credential configuration with the AI Text Generator
Lorem Ipsum
- Adds a text icon button to the CKEditor toolbar
- Opens a dialog to select the number of paragraphs (1-20, default 3)
- Inserts Lorem Ipsum placeholder text at the cursor position
Per-Site Configuration
- Dedicated backend module (Web > AI Writer) with page tree navigation for per-site credential management
- Encrypted API key storage — API keys are encrypted at rest using Sodium (derived from TYPO3's
encryptionKey) - Global fallback — sites without per-site config automatically use the global extension configuration
- Site-aware middleware — resolves the current site from page context to load the correct credentials
Credential Handling
- Production mode: API credentials configured server-side, displayed blinded to editors
- Developer mode: Optional per-user credential overrides via browser localStorage
Requirements
- TYPO3 12.4 LTS, 13.x, or 14.x
- PHP 8.1+
typo3/cms-rte-ckeditor- An Azure OpenAI resource or an OpenAI API key
Installation
Composer (recommended)
composer require oliverkroener/ok-ai-writer
Local path repository
Add the package to your repositories and require sections in composer.json:
{
"repositories": [
{
"type": "path",
"url": "packages/*"
}
],
"require": {
"oliverkroener/ok-ai-writer": "@dev"
}
}
Then run:
composer update oliverkroener/ok-ai-writer
Activate the extension
vendor/bin/typo3 extension:setup vendor/bin/typo3 database:updateschema vendor/bin/typo3 cache:flush
The database:updateschema step creates the tx_okaiwriter_configuration table used for per-site credential storage.
Configuration
Global Extension Configuration
Open Admin Tools > Settings > Extension Configuration > ok_ai_writer to set the global defaults:
| Setting | Type | Default | Description |
|---|---|---|---|
devMode |
boolean | false |
Allow editors to override credentials in localStorage |
mode |
select | azure |
AI provider: azure or openai |
apiUrl |
string | — | API endpoint URL |
apiKey |
string | — | API key (displayed blinded to editors) |
model |
string | gpt-4o |
Model name (OpenAI mode only, ignored for Azure) |
These values serve as the global fallback for sites without per-site configuration.
Per-Site Configuration (Backend Module)
Navigate to Web > AI Writer in the TYPO3 backend and select a page from the page tree. The module resolves the site root and lets you configure credentials per site:
- Developer Mode — toggle per-user credential overrides
- API Mode — Azure OpenAI or OpenAI (ChatGPT)
- API URL — endpoint URL for the selected provider
- API Key — stored encrypted in the database (Sodium encryption derived from TYPO3's
encryptionKey) - Model — model name (OpenAI mode only)
If no per-site configuration is set, the global extension configuration is used as fallback. The module displays an info banner when the global fallback is active.
Note: The backend module requires admin access and a configured TYPO3 site for the selected page.
RTE Preset Setup
Import the AI Writer YAML into your custom RTE preset and add aiText, aiTranslate, and loremIpsum to your toolbar:
# Your custom RTE preset (e.g. EXT:site_package/Configuration/RTE/MyPreset.yaml) imports: - { resource: 'EXT:rte_ckeditor/Configuration/RTE/Default.yaml' } - { resource: 'EXT:ok_ai_writer/Configuration/RTE/AiWriter.yaml' } editor: config: toolbar: items: - bold - italic # ... your other toolbar items ... - sourceEditing - loremIpsum - aiText - aiTranslate
Register your preset in ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['my_preset'] = 'EXT:site_package/Configuration/RTE/MyPreset.yaml';
And activate it via page TSconfig:
RTE.default.preset = my_preset
Provider Setup
Azure OpenAI
- Create an Azure OpenAI resource in the Azure Portal
- Deploy a model (e.g.
gpt-4,gpt-4o,gpt-35-turbo) - Set
mode = azure,apiUrlto your deployment endpoint,apiKeyto your Azure key - Endpoint URL format:
https://{resource-name}.openai.azure.com/openai/deployments/{deployment-name}/chat/completions?api-version=2024-02-01
OpenAI (ChatGPT)
- Create an API key at platform.openai.com
- Set
mode = openai,apiUrl = https://api.openai.com/v1/chat/completions,apiKeyto yoursk-...key - Set
modelto the desired model (e.g.gpt-4o,gpt-4,gpt-3.5-turbo)
Architecture
Browser (CKEditor plugin)
│
│ POST /typo3/ajax/ok-ai-writer/generate (AI Text)
│ POST /typo3/ajax/ok-ai-writer/translate (AI Translate)
│ Body: { messages[], siteRootPageId } (+ optional endpoint/apikey/mode/model in devMode)
│
▼
TYPO3 Backend (AiTextController)
│ Resolves credentials via ConfigurationService:
│ 1. Per-site DB config (tx_okaiwriter_configuration)
│ 2. Global extension config (fallback)
│ In devMode: client values override server config
│
├── mode=azure → POST with api-key header
└── mode=openai → POST with Bearer token + model in body
│
▼
AI Provider API → Response flows back to CKEditor
Configuration Resolution
ConfigurationService.getConfiguration(siteRootPageId)
│
├── siteRootPageId > 0 → AiWriterConfigurationRepository
│ │ (tx_okaiwriter_configuration table)
│ ├── per-site config found with apiUrl → use per-site config
│ └── no per-site config → fall through to global
│
└── Global ExtensionConfiguration (ext_conf_template.txt)
File Structure
packages/ok_ai_writer/
├── Classes/
│ ├── Controller/
│ │ ├── AiTextController.php # AJAX proxy controller (generate + translate)
│ │ └── Backend/
│ │ └── ConfigurationController.php # Backend module controller (edit + save)
│ ├── Domain/
│ │ └── Repository/
│ │ └── AiWriterConfigurationRepository.php # Per-site config DB layer
│ ├── Middleware/
│ │ └── AddLanguageLabels.php # Injects labels + site-aware config into backend JS
│ └── Service/
│ ├── ConfigurationService.php # Config resolution (per-site → global fallback)
│ └── EncryptionService.php # Sodium encryption for API keys
├── Configuration/
│ ├── Backend/
│ │ ├── AjaxRoutes.php # Registers /ok-ai-writer/generate and /translate
│ │ └── Modules.php # Registers Web > AI Writer backend module
│ ├── Icons.php # Extension icon registration
│ ├── JavaScriptModules.php # JS import map registration
│ ├── RequestMiddlewares.php # Registers AddLanguageLabels middleware
│ ├── RTE/
│ │ └── AiWriter.yaml # CKEditor plugin module imports
│ └── Services.yaml # DI autowiring
├── Resources/
│ ├── Private/
│ │ ├── Language/
│ │ │ ├── locallang.xlf # English labels (CKEditor plugins)
│ │ │ ├── de.locallang.xlf # German labels (CKEditor plugins)
│ │ │ ├── locallang_be_module.xlf # English labels (backend module)
│ │ │ └── de.locallang_be_module.xlf # German labels (backend module)
│ │ └── Templates/Backend/Configuration/
│ │ └── Edit.html # Fluid template for backend module form
│ └── Public/
│ ├── Icons/
│ │ └── Extension.svg # Extension icon
│ └── JavaScript/
│ ├── backend/
│ │ └── form-dirty-check.js # Unsaved changes detection for backend module
│ └── plugin/
│ ├── ai-text.js # CKEditor 5 AI text plugin
│ ├── ai-translate.js # CKEditor 5 AI translate plugin
│ └── lorem-ipsum.js # CKEditor 5 Lorem Ipsum plugin
├── Documentation/ # RST documentation
├── composer.json
├── ext_conf_template.txt # Global extension configuration
├── ext_emconf.php
├── ext_localconf.php
└── ext_tables.sql # Database schema (tx_okaiwriter_configuration)
License
GPL-2.0-or-later
Author
Oliver Kroener — oliver-kroener.de — ok@oliver-kroener.de