PHPackages                             oliverkroener/ok-ai-writer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. oliverkroener/ok-ai-writer

ActiveTypo3-cms-extension[Localization &amp; i18n](/categories/localization)

oliverkroener/ok-ai-writer
==========================

AI Text Generator for CKEditor in TYPO3 - Azure OpenAI integration

2.0.3(4mo ago)025GPL-2.0-or-laterJavaScriptPHP &gt;=8.1

Since Feb 14Pushed 3w agoCompare

[ Source](https://github.com/oliverkroener/ok_ai_writer)[ Packagist](https://packagist.org/packages/oliverkroener/ok-ai-writer)[ Docs](https://www.oliver-kroener.de)[ RSS](/packages/oliverkroener-ok-ai-writer/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (2)Versions (8)Used By (0)

AI Writer for CKEditor (ok\_ai\_writer)
=======================================

[](#ai-writer-for-ckeditor-ok_ai_writer)

[![TYPO3 12](https://camo.githubusercontent.com/2684d7b10857a7fbe915ab7d09d7f77e12dd4ad82d59d74d33de17e09c6939a6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5459504f332d31322d6f72616e67653f6c6f676f3d7479706f33)](https://get.typo3.org/version/12)[![TYPO3 13](https://camo.githubusercontent.com/dd8defc1bd50d5ea9806215644f9b57c5c16a94a7dd0fc400d4b9ff87e3a7874/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5459504f332d31332d6f72616e67653f6c6f676f3d7479706f33)](https://get.typo3.org/version/13)[![TYPO3 14](https://camo.githubusercontent.com/e529124be6a5d4fa54f1e7947268a827ebb324837ad7d64b2eaf2dea68a14b83/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5459504f332d31342d6f72616e67653f6c6f676f3d7479706f33)](https://get.typo3.org/version/14)[![PHP 8.1+](https://camo.githubusercontent.com/3e41095f4ad1c6ad78f988bd1c107f87972f334143c3ba814165a03e1f43a63c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![CKEditor 5](https://camo.githubusercontent.com/8a0dc82ac4a9487f1ec4b9a73e54bc204f082ffb535167a43b2721afb339b41b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f434b456469746f722d352d3032383744303f6c6f676f3d636b656469746f7234266c6f676f436f6c6f723d7768697465)](https://ckeditor.com/ckeditor-5/)[![License: GPL v2+](https://camo.githubusercontent.com/6453309dcfa061355d200754f7c0067d22bebd9d9c754ce6b9216176e797e8ee/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c25323076322532422d626c7565)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)[![Version](https://camo.githubusercontent.com/4ab9244fc3153b0d6f9ddd208cb213a8820c8511e2f8e875c6f1be323967d929/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d322e302e322d677265656e)](https://github.com/oliverkroener/ok_ai_writer)

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
--------

[](#features)

### AI Text Generator

[](#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

[](#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), Español, Français, Italiano, Türkçe
- 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

[](#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

[](#per-site-configuration)

- Dedicated **backend module** (Web &gt; 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

### Dark Mode Support

[](#dark-mode-support)

- All dialogs automatically adapt to the TYPO3 backend's **dark mode** setting
- Detects TYPO3's `data-color-scheme` attribute (`dark`, `light`, or `auto`)
- Falls back to `prefers-color-scheme` media query for the `auto` setting
- Full themed color palette for backgrounds, text, borders, inputs, buttons, and status indicators

### Credential Handling

[](#credential-handling)

- **Production mode**: API credentials configured server-side, displayed blinded to editors
- **Developer mode**: Optional per-user credential overrides via browser localStorage

Requirements
------------

[](#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
------------

[](#installation)

### Composer (recommended)

[](#composer-recommended)

```
composer require oliverkroener/ok-ai-writer
```

### Local path repository

[](#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

[](#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
-------------

[](#configuration)

### Global Extension Configuration

[](#global-extension-configuration)

Open **Admin Tools &gt; Settings &gt; Extension Configuration &gt; ok\_ai\_writer** to set the global defaults:

SettingTypeDefaultDescription`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)

[](#per-site-configuration-backend-module)

Navigate to **Web &gt; 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

[](#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
--------------

[](#provider-setup)

### Azure OpenAI

[](#azure-openai)

1. Create an Azure OpenAI resource in the [Azure Portal](https://portal.azure.com)
2. Deploy a model (e.g. `gpt-4`, `gpt-4o`, `gpt-35-turbo`)
3. Set `mode = azure`, `apiUrl` to your deployment endpoint, `apiKey` to your Azure key
4. Endpoint URL format: ```
    https://{resource-name}.openai.azure.com/openai/deployments/{deployment-name}/chat/completions?api-version=2024-02-01

    ```

### OpenAI (ChatGPT)

[](#openai-chatgpt)

1. Create an API key at [platform.openai.com](https://platform.openai.com)
2. Set `mode = openai`, `apiUrl = https://api.openai.com/v1/chat/completions`, `apiKey` to your `sk-...` key
3. Set `model` to the desired model (e.g. `gpt-4o`, `gpt-4`, `gpt-3.5-turbo`)

Architecture
------------

[](#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

[](#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
--------------

[](#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
-------

[](#license)

GPL-2.0-or-later

Author
------

[](#author)

**Oliver Kroener** — [oliver-kroener.de](https://www.oliver-kroener.de) —

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance86

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

5

Last Release

136d ago

Major Versions

1.0.0 → 2.0.02026-02-16

PHP version history (2 changes)1.0.0PHP &gt;=7.4

2.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/0e3131f46d9c0fc7766936f374848d0ab6be6f8095f2f2c01984736a5e7fcd52?d=identicon)[Oliver Kroener](/maintainers/Oliver%20Kroener)

---

Top Contributors

[![oliverkroener](https://avatars.githubusercontent.com/u/4545439?v=4)](https://github.com/oliverkroener "oliverkroener (1 commits)")

---

Tags

translationaiopenaiazuretypo3gpttypo3-extensionckeditor5text-generationcontent-assistant

### Embed Badge

![Health badge](/badges/oliverkroener-ok-ai-writer/health.svg)

```
[![Health](https://phpackages.com/badges/oliverkroener-ok-ai-writer/health.svg)](https://phpackages.com/packages/oliverkroener-ok-ai-writer)
```

###  Alternatives

[netresearch/rte-ckeditor-image

Image support in CKEditor for the TYPO3 ecosystem - by Netresearch

611.1M8](/packages/netresearch-rte-ckeditor-image)[smousss/laravel-globalize

Make Laravel projects translatable in a matter of seconds!

2169.2k](/packages/smousss-laravel-globalize)[t3sbs/t3sbootstrap

Startup extension to use bootstrap 5 classes, components and more out of the box. Example and info: \[www.t3sbootstrap.de\](https://www.t3sbootstrap.de)

2416.4k](/packages/t3sbs-t3sbootstrap)[stefanfroemken/repair_translation

Get rid of displaying the default file in translated records

2364.6k](/packages/stefanfroemken-repair-translation)[leuchtfeuer/locate

Locate - The users country, preferred language and other facts will be detected. Depending on configurable rules the user can be redirected to other languages or pages. Locate also provides geo blocking for configurable pages in configurable countries.

1186.6k](/packages/leuchtfeuer-locate)[netresearch/t3-cowriter

With the help of AI you can now work on a page together with a cowriter - a digital assistant that helps you to write your content.

1111.7k](/packages/netresearch-t3-cowriter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
