Skip to content

Commit 60b5735

Browse files
committed
feat: add color scheme picker to template configuration
Add 4 color fields (primary, secondary, background, text) with native TYPO3 color picker UI. Colors are passed to both structured and creative LLM prompts so the AI uses the correct brand colors. Sensible defaults: primary #0062a3, secondary #ff8700, background #fff, text #333. The prompt optimizer also includes colors in its context.
1 parent b2cdc4d commit 60b5735

File tree

9 files changed

+162
-1
lines changed

9 files changed

+162
-1
lines changed

Classes/Domain/Model/Template.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public function __construct(
3030
public string $promptOptimizerMetaPrompt = '',
3131
public int $imageTask = 0,
3232
public string $generationMode = 'structured',
33+
public string $colorPrimary = '#0062a3',
34+
public string $colorSecondary = '#ff8700',
35+
public string $colorBackground = '#ffffff',
36+
public string $colorText = '#333333',
3337
) {}
3438

3539
public function isCreativeMode(): bool

Classes/Service/ContentGeneratorService.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ private function formatBriefing(array $answers): string
146146
return implode("\n", $lines);
147147
}
148148

149+
private function buildColorBlock(Template $template): string
150+
{
151+
return <<<COLORS
152+
153+
--- FARBSCHEMA ---
154+
Verwende folgendes Farbschema fuer die generierten Inhalte:
155+
- Primaerfarbe (Buttons, Links, CTAs): {$template->colorPrimary}
156+
- Sekundaerfarbe (Akzente, Hover-States): {$template->colorSecondary}
157+
- Hintergrundfarbe: {$template->colorBackground}
158+
- Textfarbe: {$template->colorText}
159+
COLORS;
160+
}
161+
149162
/**
150163
* @param array<string, string> $briefingAnswers
151164
*/
@@ -163,6 +176,7 @@ private function buildContentPrompt(Template $template, array $briefingAnswers,
163176
$columnBlock = $this->buildColumnBlock($template->backendLayout, $parentPageId);
164177
$languageBlock = $this->buildLanguageBlock($outputLanguage);
165178
$jsonExample = $this->buildJsonExample($template->backendLayout, $cTypes, $parentPageId);
179+
$colorBlock = $this->buildColorBlock($template);
166180

167181
return <<<PROMPT
168182
{$template->systemPrompt}
@@ -171,6 +185,7 @@ private function buildContentPrompt(Template $template, array $briefingAnswers,
171185
{$briefing}
172186
{$cTypeMetadata}
173187
{$columnBlock}
188+
{$colorBlock}
174189
--- ANWEISUNGEN ZUR AUSGABE ---
175190
{$languageBlock}
176191
Erstelle Inhalte fuer eine Landing Page basierend auf dem obigen Kontext.
@@ -440,6 +455,7 @@ private function buildCreativePrompt(Template $template, array $briefingAnswers,
440455
{
441456
$briefing = $this->formatBriefing($briefingAnswers);
442457
$languageBlock = $this->buildLanguageBlock($outputLanguage);
458+
$colorBlock = $this->buildColorBlock($template);
443459

444460
$columnDescriptions = [];
445461
foreach ($columnMap as $colPos => $name) {
@@ -452,6 +468,7 @@ private function buildCreativePrompt(Template $template, array $briefingAnswers,
452468
453469
Briefing:
454470
{$briefing}
471+
{$colorBlock}
455472
456473
--- KREATIV-MODUS: HTML + CSS + INLINE-SVG ---
457474
{$languageBlock}

Classes/Service/PromptOptimizerService.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ public function buildStructuralContext(Template $template): string
104104
}
105105

106106
$lines[] = 'Briefing Mode: ' . $template->briefingMode;
107+
$lines[] = 'Color Scheme: Primary=' . $template->colorPrimary
108+
. ', Secondary=' . $template->colorSecondary
109+
. ', Background=' . $template->colorBackground
110+
. ', Text=' . $template->colorText;
107111

108112
if ($template->hasReferencePages()) {
109113
$lines[] = 'Reference Pages: ' . implode(', ', $template->referencePages);

Classes/Service/TemplateService.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,10 @@ private function hydrateTemplate(array $row): Template
559559
generationMode: is_string($row['generation_mode'] ?? null) && in_array($row['generation_mode'], ['structured', 'creative'], true)
560560
? $row['generation_mode']
561561
: 'structured',
562+
colorPrimary: is_string($row['color_primary'] ?? null) && $row['color_primary'] !== '' ? $row['color_primary'] : '#0062a3',
563+
colorSecondary: is_string($row['color_secondary'] ?? null) && $row['color_secondary'] !== '' ? $row['color_secondary'] : '#ff8700',
564+
colorBackground: is_string($row['color_background'] ?? null) && $row['color_background'] !== '' ? $row['color_background'] : '#ffffff',
565+
colorText: is_string($row['color_text'] ?? null) && $row['color_text'] !== '' ? $row['color_text'] : '#333333',
562566
);
563567
}
564568

Configuration/TCA/tx_nrlandingpage_domain_model_template.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
'--palette--;;prompt_optimizer',
2929
'--div--;LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tabs.content_layout',
3030
'generation_mode,allowed_ctypes,page_fields,reference_pages,backend_layout',
31+
'--palette--;;color_scheme',
3132
'--div--;LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tabs.wizard',
3233
'briefing_mode,publish_mode',
3334
'--div--;LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tabs.access',
@@ -42,6 +43,10 @@
4243
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:palette.prompt_optimizer',
4344
'showitem' => 'prompt_optimizer_context,--linebreak--,prompt_optimizer_meta_prompt',
4445
],
46+
'color_scheme' => [
47+
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:palette.color_scheme',
48+
'showitem' => 'color_primary,color_secondary,--linebreak--,color_background,color_text',
49+
],
4550
],
4651
'columns' => [
4752
'title' => [
@@ -235,6 +240,38 @@
235240
'default' => 'structured',
236241
],
237242
],
243+
'color_primary' => [
244+
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_primary',
245+
'description' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_primary.description',
246+
'config' => [
247+
'type' => 'color',
248+
'default' => '#0062a3',
249+
],
250+
],
251+
'color_secondary' => [
252+
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_secondary',
253+
'description' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_secondary.description',
254+
'config' => [
255+
'type' => 'color',
256+
'default' => '#ff8700',
257+
],
258+
],
259+
'color_background' => [
260+
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_background',
261+
'description' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_background.description',
262+
'config' => [
263+
'type' => 'color',
264+
'default' => '#ffffff',
265+
],
266+
],
267+
'color_text' => [
268+
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_text',
269+
'description' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.color_text.description',
270+
'config' => [
271+
'type' => 'color',
272+
'default' => '#333333',
273+
],
274+
],
238275
'backend_layout' => [
239276
'label' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.backend_layout',
240277
'description' => 'LLL:EXT:nr_landingpage/Resources/Private/Language/locallang_db.xlf:tx_nrlandingpage_domain_model_template.backend_layout.description',

Resources/Private/Language/de.locallang_db.xlf

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,42 @@
195195
<source>Prompt Optimization</source>
196196
<target>Prompt-Optimierung</target>
197197
</trans-unit>
198+
<trans-unit id="palette.color_scheme" resname="palette.color_scheme">
199+
<source>Color Scheme</source>
200+
<target>Farbschema</target>
201+
</trans-unit>
202+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_primary" resname="tx_nrlandingpage_domain_model_template.color_primary">
203+
<source>Primary Color</source>
204+
<target>Primärfarbe</target>
205+
</trans-unit>
206+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_primary.description" resname="tx_nrlandingpage_domain_model_template.color_primary.description">
207+
<source>Main brand color used for buttons, links, and call-to-action elements.</source>
208+
<target>Hauptfarbe der Marke für Buttons, Links und Call-to-Action-Elemente.</target>
209+
</trans-unit>
210+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_secondary" resname="tx_nrlandingpage_domain_model_template.color_secondary">
211+
<source>Secondary Color</source>
212+
<target>Sekundärfarbe</target>
213+
</trans-unit>
214+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_secondary.description" resname="tx_nrlandingpage_domain_model_template.color_secondary.description">
215+
<source>Accent color for highlights, hover states, and decorative elements.</source>
216+
<target>Akzentfarbe für Hervorhebungen, Hover-Effekte und dekorative Elemente.</target>
217+
</trans-unit>
218+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_background" resname="tx_nrlandingpage_domain_model_template.color_background">
219+
<source>Background Color</source>
220+
<target>Hintergrundfarbe</target>
221+
</trans-unit>
222+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_background.description" resname="tx_nrlandingpage_domain_model_template.color_background.description">
223+
<source>Default page and section background color.</source>
224+
<target>Standard-Hintergrundfarbe für Seiten und Abschnitte.</target>
225+
</trans-unit>
226+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_text" resname="tx_nrlandingpage_domain_model_template.color_text">
227+
<source>Text Color</source>
228+
<target>Textfarbe</target>
229+
</trans-unit>
230+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_text.description" resname="tx_nrlandingpage_domain_model_template.color_text.description">
231+
<source>Default color for body text and paragraphs.</source>
232+
<target>Standardfarbe für Fließtext und Absätze.</target>
233+
</trans-unit>
198234
<trans-unit id="fieldInformation.generatedPageCount" resname="fieldInformation.generatedPageCount">
199235
<source>%d page(s) generated with this template</source>
200236
<target>%d Seite(n) mit diesem Template generiert</target>

Resources/Private/Language/locallang_db.xlf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,33 @@
147147
<trans-unit id="palette.prompt_optimizer" resname="palette.prompt_optimizer">
148148
<source>Prompt Optimization</source>
149149
</trans-unit>
150+
<trans-unit id="palette.color_scheme" resname="palette.color_scheme">
151+
<source>Color Scheme</source>
152+
</trans-unit>
153+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_primary" resname="tx_nrlandingpage_domain_model_template.color_primary">
154+
<source>Primary Color</source>
155+
</trans-unit>
156+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_primary.description" resname="tx_nrlandingpage_domain_model_template.color_primary.description">
157+
<source>Main brand color used for buttons, links, and call-to-action elements.</source>
158+
</trans-unit>
159+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_secondary" resname="tx_nrlandingpage_domain_model_template.color_secondary">
160+
<source>Secondary Color</source>
161+
</trans-unit>
162+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_secondary.description" resname="tx_nrlandingpage_domain_model_template.color_secondary.description">
163+
<source>Accent color for highlights, hover states, and decorative elements.</source>
164+
</trans-unit>
165+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_background" resname="tx_nrlandingpage_domain_model_template.color_background">
166+
<source>Background Color</source>
167+
</trans-unit>
168+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_background.description" resname="tx_nrlandingpage_domain_model_template.color_background.description">
169+
<source>Default page and section background color.</source>
170+
</trans-unit>
171+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_text" resname="tx_nrlandingpage_domain_model_template.color_text">
172+
<source>Text Color</source>
173+
</trans-unit>
174+
<trans-unit id="tx_nrlandingpage_domain_model_template.color_text.description" resname="tx_nrlandingpage_domain_model_template.color_text.description">
175+
<source>Default color for body text and paragraphs.</source>
176+
</trans-unit>
150177
<trans-unit id="fieldInformation.generatedPageCount" resname="fieldInformation.generatedPageCount">
151178
<source>%d page(s) generated with this template</source>
152179
</trans-unit>

Tests/Unit/Domain/Model/TemplateTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,32 @@ public function getConfigHashChangesWhenGenerationModeChanges(): void
169169

170170
self::assertNotSame($a->getConfigHash(), $b->getConfigHash());
171171
}
172+
173+
#[Test]
174+
public function colorPropertiesHaveSensibleDefaults(): void
175+
{
176+
$template = new Template(uid: 1, title: 'T', identifier: 't');
177+
self::assertSame('#0062a3', $template->colorPrimary);
178+
self::assertSame('#ff8700', $template->colorSecondary);
179+
self::assertSame('#ffffff', $template->colorBackground);
180+
self::assertSame('#333333', $template->colorText);
181+
}
182+
183+
#[Test]
184+
public function colorPropertiesAcceptCustomValues(): void
185+
{
186+
$template = new Template(
187+
uid: 1,
188+
title: 'T',
189+
identifier: 't',
190+
colorPrimary: '#ff0000',
191+
colorSecondary: '#00ff00',
192+
colorBackground: '#000000',
193+
colorText: '#ffffff',
194+
);
195+
self::assertSame('#ff0000', $template->colorPrimary);
196+
self::assertSame('#00ff00', $template->colorSecondary);
197+
self::assertSame('#000000', $template->colorBackground);
198+
self::assertSame('#ffffff', $template->colorText);
199+
}
172200
}

ext_tables.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ CREATE TABLE tx_nrlandingpage_domain_model_template (
1414
prompt_optimizer_context text,
1515
prompt_optimizer_meta_prompt text,
1616
image_task int(11) unsigned NOT NULL DEFAULT 0,
17-
generation_mode varchar(20) NOT NULL DEFAULT 'structured'
17+
generation_mode varchar(20) NOT NULL DEFAULT 'structured',
18+
color_primary varchar(7) NOT NULL DEFAULT '#0062a3',
19+
color_secondary varchar(7) NOT NULL DEFAULT '#ff8700',
20+
color_background varchar(7) NOT NULL DEFAULT '#ffffff',
21+
color_text varchar(7) NOT NULL DEFAULT '#333333'
1822
);
1923

2024
CREATE TABLE pages (

0 commit comments

Comments
 (0)