AI Writer for CKEditor 

Extension key

ok_ai_writer

Package name

oliverkroener/ok-ai-writer

Version

1.0

Language

en

Author

Oliver Kroener <ok@oliver-kroener.de>

License

This document is published under the Open Publication License.

Rendered

Sat, 14 Feb 2026 22:57:35 +0000


AI Writer adds AI-powered text generation directly into CKEditor in the TYPO3 backend. Editors can generate SEO-optimized HTML content using Azure OpenAI or OpenAI (ChatGPT) — without leaving the rich text editor.

Introduction 

Learn what AI Writer does, its features, and system requirements.

Installation 

Install the extension via Composer and activate it in your TYPO3 project.

Configuration 

Set up extension settings, CKEditor toolbar, and AI provider credentials.

Usage 

Generate and refine AI content, translate text, and insert Lorem Ipsum.

Architecture 

Understand the request flow, file structure, and extension internals.

Introduction 

What is AI Writer? 

AI Writer (ok_ai_writer) is a TYPO3 extension that brings AI-powered text generation directly into CKEditor. Editors can generate, preview, and iteratively refine SEO-optimized HTML content using Azure OpenAI or OpenAI (ChatGPT) — all without leaving the rich text editor.

The extension provides three CKEditor 4 plugins:

AI Text Generator
Opens a chat-style dialog where editors describe the content they need. The AI generates well-structured HTML that can be refined through follow-up prompts before inserting it into the editor.
AI Translate
Translates the full editor content into a selected target language while preserving all HTML tags and formatting.
Lorem Ipsum
Opens a dialog to choose a paragraph count (1–20) and inserts placeholder text at the cursor position — useful during development and layout prototyping.

Features 

  • Conversational AI dialog — Chat-style interface with full conversation history for iterative content refinement.
  • SEO-optimized output — The AI generates well-structured HTML with semantic headings (<h2><h4>) and paragraphs.
  • AI translation — Translate the full editor content into any language while preserving all HTML tags and formatting.
  • Dual provider support — Works with both Azure OpenAI and OpenAI (ChatGPT) APIs. Switch between providers via extension configuration.
  • Centralized or per-user credentials — API credentials can be configured server-side by an administrator (displayed blinded to editors) or per-user in the browser's localStorage when developer mode is enabled.
  • Token usage tracking — Displays cumulative input/output token counts per session so editors stay aware of API consumption.
  • Localized UI — Ships with English and German translations.
  • Lorem Ipsum helper — Additional CKEditor plugin for quick placeholder text insertion (configurable paragraph count) during development.
  • Backend proxy — API requests are routed through the TYPO3 backend, avoiding browser CORS restrictions.

Requirements 

Component Version
TYPO3 10.4 LTS or 11.5 LTS
PHP 7.4+
CKEditor typo3/cms-rte-ckeditor ^10.4 || ^11.5
AI Provider Azure OpenAI or OpenAI (ChatGPT)

Installation 

Install via Composer 

composer require oliverkroener/ok-ai-writer
Copied!

This pulls the extension and its dependencies into your TYPO3 project.

Install from a local path 

If you develop the extension locally (e.g. in a packages/ directory), add it as a path repository in your project's composer.json:

{
    "repositories": [
        {
            "type": "path",
            "url": "packages/*"
        }
    ],
    "require": {
        "oliverkroener/ok-ai-writer": "@dev"
    }
}
Copied!

Then run:

composer update oliverkroener/ok-ai-writer
Copied!

Activate the extension 

After installing, set up and activate the extension:

vendor/bin/typo3 extension:setup
vendor/bin/typo3 cache:flush
Copied!

Verify the installation 

After activation, confirm the extension is loaded:

vendor/bin/typo3 extension:list | grep ok_ai_writer
Copied!

You should see ok_ai_writer in the output. The CKEditor plugins are now available for configuration.

Configuration 

The extension supports two AI providers — Azure OpenAI and OpenAI (ChatGPT) — and can be configured either centrally by an administrator or per-user in developer mode.

Extension configuration 

Open Admin Tools > Settings > Extension Configuration > ok_ai_writer to set the following options:

devMode

devMode
type

boolean

Default

false

When enabled, editors can override API credentials in their browser (localStorage). When disabled, only the server-side credentials configured below are used.

mode

mode
type

select

Default

azure

The AI provider to use.

azure
Azure OpenAI — uses the api-key header for authentication.
openai
OpenAI (ChatGPT) — uses Authorization: Bearer header and sends the model parameter in the request body.

apiUrl

apiUrl
type

string

Default

(empty)

The API endpoint URL.

Azure example:

https://<resource>.openai.azure.com/openai/deployments/<model>/chat/completions?api-version=2024-02-01
Copied!

OpenAI example:

https://api.openai.com/v1/chat/completions
Copied!

apiKey

apiKey
type

string

Default

(empty)

The API key for the selected provider. This value is displayed blinded (masked) to editors in the CKEditor dialog — they can see that credentials are configured but cannot read the actual value.

model

model
type

string

Default

gpt-4o

The model to use in OpenAI mode (e.g. gpt-4o, gpt-4, gpt-3.5-turbo). This setting is ignored in Azure mode, where the model is part of the endpoint URL.

Developer mode 

When devMode is enabled:

  • Editors see a full settings panel in the AI dialog with editable fields for mode, endpoint URL, API key, and model.
  • Client-entered credentials are saved in localStorage and override the server-side configuration.
  • Server-configured values are shown as blinded hints below each field (e.g. http****************2001).
  • If no client credentials are entered, the server-side config is used as fallback.

Step 1: Register the CKEditor plugins 

The extension ships an RTE preset at EXT:ok_ai_writer/Configuration/RTE/Default.yaml that registers all three CKEditor 4 external plugins and adds an ai toolbar group. You can either use it directly or import it into your own preset.

Option B: Use the bundled RTE preset 

The extension registers an RTE preset called ok_ai_writer. To use it directly, add to your Page TSconfig:

RTE.default.preset = ok_ai_writer
Copied!

Toolbar button names 

Button name Description
AiText AI Text Generator (sparkle icon)
AiTranslate AI Translate (globe icon)
LoremIpsum Lorem Ipsum placeholder text (text icon)

Step 2: Set up your AI provider 

Azure OpenAI 

  1. Create an Azure OpenAI resource in the Azure Portal.
  2. Deploy a model (e.g. gpt-4, gpt-4o, gpt-35-turbo).
  3. Copy the Endpoint and Key from the resource's "Keys and Endpoint" page.
  4. In the extension configuration, set:

    • mode = azure
    • apiUrl = https://<resource>.openai.azure.com/openai/deployments/<model>/chat/completions?api-version=2024-02-01
    • apiKey = your Azure API key

OpenAI (ChatGPT) 

  1. Create an account at platform.openai.com and generate an API key.
  2. In the extension configuration, set:

    • mode = openai
    • apiUrl = https://api.openai.com/v1/chat/completions
    • apiKey = your sk-... API key
    • model = gpt-4o (or another available model)

Usage 

AI Text Generator 

The AI Text Generator lets you create and iteratively refine content through a conversational interface.

Generating content 

  1. Place your cursor in a CKEditor field where you want to insert content.
  2. Click the AI Text toolbar button (sparkle icon).
  3. In the dialog, type a prompt describing the content you need, e.g. "Write an introduction about sustainable urban planning".
  4. Press Enter or click the send button.
  5. The generated HTML content appears in the preview area.

Refining content 

After the initial generation, you can refine the result with follow-up instructions:

  1. Type a follow-up instruction in the input field, e.g. "make it shorter", "more formal", or "add a call to action".
  2. The AI retains the full conversation context and adjusts the content accordingly.
  3. Repeat until you're satisfied with the result.

Inserting into the editor 

  1. Click Insert into Editor to insert the final content at the cursor
    position in CKEditor.

The dialog closes automatically and focus returns to the editor.

Keyboard shortcuts 

Shortcut Action
Enter Send prompt / generate text
Shift + Enter New line in the prompt input
Escape Close the dialog

Token tracking 

The dialog displays cumulative input and output token counts at the bottom right corner. This helps editors monitor API usage during a session.

AI Translate 

The AI Translate plugin translates the full editor content into a target language while preserving all HTML tags and formatting.

Translating content 

  1. Enter or select content in a CKEditor field.
  2. Click the AI Translate toolbar button (globe icon).
  3. Select the target language from the dropdown.
  4. Click Translate. The entire editor content is replaced with the translated version.

Lorem Ipsum 

The Lorem Ipsum plugin inserts placeholder text for layout prototyping.

  1. Place the cursor where you want the text inserted.
  2. Click the Lorem Ipsum toolbar button (text lines icon).
  3. In the dialog, choose the number of paragraphs (1–20).
  4. Click Insert. The selected number of Lorem Ipsum paragraphs are inserted at the cursor position.

Architecture 

This section describes the internal architecture of the AI Writer extension for developers who want to understand, extend, or debug the extension.

Request flow 

Browser (CKEditor Plugin)
    │
    │  User types prompt in the AI dialog
    │
    ▼
TYPO3 AJAX Route
    POST /typo3/ajax/ok-ai-writer/generate
    Body: { messages[] }              (production mode)
    Body: { endpoint, apikey, mode,   (dev mode — optional overrides)
            model, messages[] }
    │
    ▼
AiTextController::generateAction()
    │  Reads extension configuration (mode, apiUrl, apiKey, model)
    │  In devMode: client values override server config
    │  Prepends SEO system prompt
    │
    ├── mode=azure ──▶  Azure OpenAI API  (api-key header)
    │
    └── mode=openai ──▶  OpenAI API  (Bearer token + model in body)
    │
    │  Returns: choices[].message.content (HTML)
    │           usage.prompt_tokens / completion_tokens
    │
    ▼
Response flows back to CKEditor
    │  Displayed in preview area
    │  Added to conversation history
    ▼
Editor clicks "Insert into Editor"
    Content inserted at cursor position
Copied!

System prompt 

The controller prepends a system message (identical for both providers) that instructs the AI to:

  • Generate well-structured, SEO-optimized HTML content
  • Use semantic headings (<h2>, <h3>, <h4>) and paragraphs
  • Not include <h1> tags (the page already has one)
  • Not include markdown formatting, code fences, or explanations
  • Return only clean HTML

Provider modes 

The controller supports two AI providers, selected via the mode extension configuration:

Azure OpenAI (mode = azure)
Authenticates via api-key HTTP header. The model is determined by the deployment name in the endpoint URL. No model parameter is sent in the request body.
OpenAI / ChatGPT (mode = openai)
Authenticates via Authorization: Bearer <key> header. The model parameter (e.g. gpt-4o) is included in the JSON request body.

Conversation mode 

The plugin supports two message modes:

Conversation mode (default)
The browser sends the full messages[] array (user + assistant turns). The controller prepends the system prompt and forwards the entire history to the AI API. This enables iterative refinement.
Legacy single-prompt mode
If no messages[] array is sent, the controller falls back to using a single prompt string. This mode exists for backwards compatibility.

Key files 

Classes/
├── Controller/
│   └── AiTextController.php         AJAX endpoint — proxies to AI API
└── Middleware/
    └── AddLanguageLabels.php        Injects XLIFF labels + config into backend JS

Configuration/
├── Backend/
│   └── AjaxRoutes.php               Registers /ok-ai-writer/generate + /translate
├── RequestMiddlewares.php           Registers AddLanguageLabels middleware
├── RTE/
│   └── Default.yaml                CKEditor 4 external plugin registration
└── Services.yaml                    Symfony DI autowiring

Resources/
├── Private/Language/
│   ├── locallang.xlf                English labels
│   └── de.locallang.xlf             German labels
└── Public/CKEditor/Plugins/
    ├── AiText/plugin.js             CKEditor 4 AI Text plugin
    ├── AiTranslate/plugin.js        CKEditor 4 AI Translate plugin
    └── LoremIpsum/plugin.js         CKEditor 4 Lorem Ipsum plugin
Copied!

Component details 

AiTextController 

File

Classes/Controller/AiTextController.php

Routes

/ok-ai-writer/generate and /ok-ai-writer/translate (AJAX, POST)

Receives the conversation messages from the browser. Reads API credentials from extension configuration (or from the request in devMode). Prepends the SEO system prompt (for generate) or translation system prompt (for translate), forwards to the configured AI provider via Guzzle HTTP client, and returns the JSON response.

  • Reads devMode, mode, apiUrl, apiKey, model from extension configuration
  • In devMode: client-sent credentials override server config
  • Supports both Azure (api-key header) and OpenAI (Bearer token)
  • Supports both messages[] (conversation) and prompt (legacy) input
  • Uses temperature: 0.3 and max_tokens: 2000 (4000 for translate)
  • Timeout: 120 seconds
  • Returns API errors as HTTP 502 with the first 500 characters of the error response

AddLanguageLabels middleware 

File

Classes/Middleware/AddLanguageLabels.php

Stack

Backend middleware

Injects the extension's XLIFF translation labels into the TYPO3 backend page renderer so they are available via TYPO3.lang in JavaScript. Also injects extension configuration as inline settings (TYPO3.settings.ok_ai_writer) with blinded credential values.

CKEditor plugins 

All three plugins are self-contained CKEditor 4 IIFEs registered via externalPlugins in Configuration/RTE/Default.yaml. Each uses CKEDITOR.plugins.add() with editor.addCommand() and editor.ui.addButton() for toolbar integration.

AiText/plugin.js
Registers the AiText toolbar button. On click, creates a modal overlay with a chat-style dialog. Handles conversation state, API calls via XHR, token tracking, and content insertion via editor.insertHtml().
AiTranslate/plugin.js
Registers the AiTranslate toolbar button. On click, opens a language selector dialog. Sends the full editor content to the translate endpoint and replaces it with the translated HTML.
LoremIpsum/plugin.js
Registers the LoremIpsum toolbar button. On click, opens a dialog to choose the number of paragraphs (1–20) and inserts Lorem Ipsum text at the cursor position.

Localization 

The extension ships with two language files:

File Language
Resources/Private/Language/locallang.xlf English
Resources/Private/Language/de.locallang.xlf German

Labels are loaded into the backend via the AddLanguageLabels middleware and accessed in JavaScript through TYPO3.lang['label.key'].

To add a new translation, create a file named <language-code>.locallang.xlf (e.g. fr.locallang.xlf) following the XLIFF 1.2 format.

License 

This extension is licensed under the GNU General Public License v2.0 or later.

Author

Oliver Kroener <ok@oliver-kroener.de>