in2code/alternative
最新稳定版本:2.0.0
Composer 安装命令:
composer require in2code/alternative
包简介
Automatically set alternative texts for images
README 文档
README
Introduction
This TYPO3 extension allows setting alternative texts, title labels and a description for images in a filestorage. This can be done via file list backend module or via command on the CLI.
Example metadata labels from AI:

Google Gemini API
- To use the extension, you need a Google Gemini API key. You can register for one at https://aistudio.google.com/app/api-keys.
- Alternatively, you can implement your own LLM provider (see Custom LLM Integration below).
Installation
composer req in2code/alternative
After that, you have to set some initial configuration in Extension Manager configuration:
| Title | Default value | Description |
|---|---|---|
| setAlternative | 1 | Toggle function: Set a value for alternative text |
| setTitle | 1 | Toggle function: Set a value for image title |
| setDescription | 1 | Toggle function: Set a value for a description |
| showButtonInFileList | 1 | Show or hide button in backend module file list |
| apiKey | - | Google Gemini API key. You can let this value empty and simply use ENV_VAR "GOOGLE_API_KEY" instead if you want to use CI pipelines for this setting |
| limitToLanguages | - | If set, limit to this language identifiers only. Use a commaseparated list of numbers |
Note: It's recommended to use ENV vars for in2code/alternative instead of saving the API-Key in Extension Manager configuration
GOOGLE_API_KEY=your_api_key_from_google
CLI commands
# Set metadata for all image files in storage 1
./vendor/bin/typo3 alternative:set "1:/"
# Set metadata for all image files in a subfoler in storage 1 (maybe "fileadmin/in2code/folder/")
./vendor/bin/typo3 alternative:set "1:/in2code/folder/"
# Enforce to set metadata for all image files in storage 1
./vendor/bin/typo3 alternative:set "1:/" 1
Custom LLM Integration (like ChatGPT, Claude, Mistral, etc.)
Alternative uses a factory pattern to allow custom LLM providers. By default, it uses Google Gemini, but you can easily integrate other AI services (OpenAI, Claude, local models, etc.).
Implementing a Custom LLM Repository
- Create a custom repository class implementing
RepositoryInterface- see example for OpenAI ChatGPT:
<?php declare(strict_types=1); namespace Vendor\MyExtension\Domain\Repository\Llm; use In2code\Alternative\Domain\Repository\Llm\AbstractRepository; use In2code\Alternative\Domain\Repository\Llm\RepositoryInterface; use In2code\Alternative\Exception\ApiException; use In2code\Alternative\Exception\ConfigurationException; use TYPO3\CMS\Core\Http\RequestFactory; use TYPO3\CMS\Core\Resource\File; class ChatGptRepository extends AbstractRepository implements RepositoryInterface { private string $apiKey = ''; private string $apiUrl = 'https://api.openai.com/v1/chat/completions'; public function __construct( protected RequestFactory $requestFactory, ) { parent::__construct($requestFactory); $this->apiKey = getenv('OPENAI_API_KEY') ?: ''; } public function checkApiKey(): void { if ($this->apiKey === '') { throw new ConfigurationException('OpenAI API key not configured', 1735646000); } } public function getApiUrl(): string { return $this->apiUrl; } public function analyzeImage(File $file, string $languageCode): array { $this->checkApiKey(); $this->setLanguageCode($languageCode); $imageData = base64_encode($file->getContents()); return $this->generateMetadataWithChatGpt($imageData, $file->getMimeType()); } protected function generateMetadataWithChatGpt(string $imageData, string $mimeType): array { $payload = [ 'model' => 'gpt-4o', 'messages' => [ [ 'role' => 'user', 'content' => [ ['type' => 'text', 'text' => $this->getPrompt()], [ 'type' => 'image_url', 'image_url' => [ 'url' => 'data:' . $mimeType . ';base64,' . $imageData, ], ], ], ], ], 'temperature' => 0.1, 'max_tokens' => 500, ]; $options = [ 'headers' => [ 'Authorization' => 'Bearer ' . $this->apiKey, 'Content-Type' => 'application/json', ], 'body' => json_encode($payload), ]; $response = $this->requestFactory->request($this->getApiUrl(), $this->requestMethod, $options); if ($response->getStatusCode() !== 200) { throw new ApiException( 'Failed to analyze image with ChatGPT: ' . $response->getBody()->getContents(), 1735646001 ); } $responseData = json_decode($response->getBody()->getContents(), true); return $this->parseResponse($responseData); } protected function parseResponse(array $responseData): array { if (isset($responseData['choices'][0]['message']['content']) === false) { throw new ApiException('Invalid ChatGPT API response structure', 1735646002); } $text = $responseData['choices'][0]['message']['content']; // Extract JSON from markdown code blocks if present if (preg_match('/```json\s*(\{.*?\})\s*```/s', $text, $matches)) { $text = $matches[1]; } elseif (preg_match('/```\s*(\{.*?\})\s*```/s', $text, $matches)) { $text = $matches[1]; } $data = json_decode($text, true); if ($data === null) { throw new ApiException('Could not parse ChatGPT response as JSON', 1735646003); } return [ 'title' => $data['title'] ?? '', 'description' => $data['description'] ?? '', 'alternativeText' => $data['alternativeText'] ?? '', ]; } }
- Register your custom repository in
ext_localconf.php:
<?php defined('TYPO3') || die(); // Register custom LLM repository $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['alternative']['llmRepositoryClass'] = \Vendor\MyExtension\Domain\Repository\Llm\ChatGptRepository::class;
Hint: Don't forget to register your Repository in your Services.yaml and flush caches
Changelog and breaking changes
| Version | Date | State | Description |
|---|---|---|---|
| 2.0.0 | 2025-12-31 | Feature | Prepare overruling of the GeminiRepository |
| 1.2.0 | 2025-12-07 | Feature | Support TYPO3 14, use better titles and icons, decrease length for metadata, skip missing images |
| 1.1.0 | 2025-12-04 | Feature | Add ddev as local environment, prevent syntax error in PHP 8.2 |
| 1.0.0 | 2025-12-03 | Task | Initial release of in2code/alternative |
Contribution with ddev
This repository provides a DDEV-backed development environment. If DDEV is installed, simply run the following commands to quickly set up a local environment with example usages:
ddev startddev initialize
Backend Login:
Username: admin
Password: admin
Installation hint:
- Install ddev before, see: https://ddev.readthedocs.io/en/stable/#installation
- Install git-lfs before, see: https://git-lfs.github.com/
- Add the API key in
.ddev/.envlike
GOOGLE_API_KEY=your_api_key_from_google
统计信息
- 总下载量: 21
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: GPL-2.0-or-later
- 更新时间: 2025-12-03

