@@ -52,7 +52,10 @@ public function processNode(
52
52
Directive $ directive ,
53
53
): Node {
54
54
try {
55
- $ contents = $ this ->loadFileFromDocumentation ($ blockContext , $ directive );
55
+ // The path delivered via the directive like:
56
+ // .. typo3:site-set-settings:: PROJECT:/Configuration/Sets/FluidStyledContent/settings.definitions.yaml
57
+ $ setConfigurationFile = $ directive ->getData ();
58
+ $ contents = $ this ->loadFileFromDocumentation ($ blockContext , $ setConfigurationFile );
56
59
// Parse the YAML content
57
60
$ yamlData = Yaml::parse ($ contents );
58
61
@@ -63,14 +66,60 @@ public function processNode(
63
66
$ this ->logger ->warning ($ exception ->getMessage (), $ blockContext ->getLoggerInformation ());
64
67
return $ this ->getErrorNode ();
65
68
}
66
- return $ this ->buildConfvalMenu ($ directive , $ yamlData ['settings ' ]);
69
+
70
+
71
+ $ labelsFile = null ;
72
+ try {
73
+ $ configYamlFile = dirname ($ setConfigurationFile ) . '/config.yaml ' ;
74
+ $ contents = $ this ->loadFileFromDocumentation ($ blockContext , $ configYamlFile );
75
+ // Parse the YAML content
76
+ $ configYamlData = Yaml::parse ($ contents );
77
+
78
+ if (is_array ($ configYamlData )) {
79
+ $ labelsFile = $ configYamlData ['labels ' ] ?? null ;
80
+ }
81
+ } catch (FileLoadingException $ exception ) {
82
+ // ignore, config.yaml isn't required
83
+ }
84
+
85
+ $ labelContents = '' ;
86
+ if ($ labelsFile ) {
87
+ // Asume all EXT: references are relative to the rendered PROJECT
88
+ $ labelsFile = preg_replace ('/^EXT:[^\/]*\// ' , 'PROJECT:/ ' , $ labelsFile );
89
+ try {
90
+ $ labelContents = $ this ->loadFileFromDocumentation ($ blockContext , $ labelsFile );
91
+ } catch (FileLoadingException $ exception ) {
92
+ // ignore, config.yaml isn't required
93
+ }
94
+ }
95
+ $ labels = [];
96
+ $ descriptions = [];
97
+ if ($ labelContents ) {
98
+ $ xml = new \DOMDocument ();
99
+ if ($ xml ->loadXML ($ labelContents )) {
100
+ foreach ($ xml ->getElementsByTagName ('trans-unit ' ) as $ label ) {
101
+ $ id = $ label ->getAttribute ('id ' );
102
+ $ value = ($ label ->getElementsByTagName ('source ' )[0 ] ?? null )?->textContent ?? '' ;
103
+ if (!$ value ) {
104
+ continue ;
105
+ }
106
+ if (str_starts_with ($ id , 'settings.description. ' )) {
107
+ $ descriptions [substr ($ id , 21 )] = $ value ;
108
+ } elseif (str_starts_with ($ id , 'settings. ' )) {
109
+ $ labels [substr ($ id , 9 )] = $ value ;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return $ this ->buildConfvalMenu ($ directive , $ yamlData ['settings ' ], $ labels , $ descriptions );
67
116
}
68
117
69
118
/**
70
119
* @throws \League\Flysystem\FileNotFoundException
71
120
* @throws FileLoadingException
72
121
*/
73
- public function loadFileFromDocumentation (BlockContext $ blockContext , Directive $ directive ): string
122
+ public function loadFileFromDocumentation (BlockContext $ blockContext , string $ filename ): string
74
123
{
75
124
$ parser = $ blockContext ->getDocumentParserContext ()->getParser ();
76
125
$ parserContext = $ parser ->getParserContext ();
@@ -80,10 +129,6 @@ public function loadFileFromDocumentation(BlockContext $blockContext, Directive
80
129
$ adapter = $ origin ->getAdapter ();
81
130
$ pathPrefix = (string )$ adapter ->getPathPrefix ();
82
131
83
- // The path delivered via the directive like:
84
- // .. typo3:site-set-settings:: PROJECT:/Configuration/Sets/FluidStyledContent/settings.definitions.yaml
85
- $ setConfigurationFile = $ directive ->getData ();
86
-
87
132
// By default, the RST files are placed inside a "Documentation" subdirectory.
88
133
// When using the docker container, this origin root path is then set to "/project/Documentation".
89
134
// No files on the "/project/" directory level can usually be accessed, even though they may belong
@@ -92,19 +137,19 @@ public function loadFileFromDocumentation(BlockContext $blockContext, Directive
92
137
// a special string "PROJECT:" is evaluated here.
93
138
// If a path starts with that notation, it will be referenced from the "/project/..." directory level.
94
139
// It will not break out of the "/project/" mapping!
95
- if (str_starts_with ($ setConfigurationFile , 'PROJECT: ' )) {
140
+ if (str_starts_with ($ filename , 'PROJECT: ' )) {
96
141
// This will replace "PROJECT:/Configuration/Sets/File.yaml" with "/Configuration/Sets/File.yaml"
97
142
// and is then passed to absoluteRelativePath() which will set $path = "/Configuration/Sets/File.yaml",
98
143
// but ensure no "../../../" or other path traversal is allowed.
99
- $ path = $ parserContext ->absoluteRelativePath (str_replace ('PROJECT: ' , '' , $ setConfigurationFile ));
144
+ $ path = $ parserContext ->absoluteRelativePath (str_replace ('PROJECT: ' , '' , $ filename ));
100
145
101
146
// Get the current origin Path, usually "/project/Documentation/", and go one level up.
102
147
$ newOriginPath = dirname ($ pathPrefix ) . '/ ' ;
103
148
104
149
// Temporarily change the path prefix now to "/project/"
105
150
$ adapter ->setPathPrefix ($ newOriginPath );
106
151
} else {
107
- $ path = $ parserContext ->absoluteRelativePath ($ setConfigurationFile );
152
+ $ path = $ parserContext ->absoluteRelativePath ($ filename );
108
153
}
109
154
110
155
if (!$ origin ->has ($ path )) {
@@ -133,8 +178,10 @@ private function getErrorNode(): ParagraphNode
133
178
134
179
/**
135
180
* @param array<string, array<string, string>> $settings
181
+ * @param array<string, string> $labels
182
+ * @param array<string, string> $descriptions
136
183
*/
137
- public function buildConfvalMenu (Directive $ directive , array $ settings ): ConfvalMenuNode
184
+ public function buildConfvalMenu (Directive $ directive , array $ settings, array $ labels , array $ descriptions ): ConfvalMenuNode
138
185
{
139
186
$ idPrefix = '' ;
140
187
if ($ directive ->getOptionString ('name ' ) !== '' ) {
@@ -143,7 +190,7 @@ public function buildConfvalMenu(Directive $directive, array $settings): Confval
143
190
144
191
$ confvals = [];
145
192
foreach ($ settings as $ key => $ setting ) {
146
- $ confvals [] = $ this ->buildConfval ($ setting , $ idPrefix , $ key , $ directive );
193
+ $ confvals [] = $ this ->buildConfval ($ setting , $ idPrefix , $ key , $ directive, $ labels , $ descriptions );
147
194
}
148
195
$ reservedParameterNames = [
149
196
'name ' ,
@@ -182,22 +229,26 @@ public function buildConfvalMenu(Directive $directive, array $settings): Confval
182
229
183
230
/**
184
231
* @param array<string, scalar|array<string, scalar>> $setting
232
+ * @param array<string, string> $labels
233
+ * @param array<string, string> $descriptions
185
234
*/
186
- public function buildConfval (array $ setting , string $ idPrefix , string $ key , Directive $ directive ): ConfvalNode
235
+ public function buildConfval (array $ setting , string $ idPrefix , string $ key , Directive $ directive, array $ labels , array $ descriptions ): ConfvalNode
187
236
{
188
237
$ content = [];
189
- if (is_string ($ setting ['description ' ] ?? false )) {
238
+ $ description = $ setting ['description ' ] ?? $ descriptions [$ key ] ?? false ;
239
+ if (is_string ($ description )) {
190
240
$ content [] = new ParagraphNode ([
191
- new InlineCompoundNode ([new PlainTextInlineNode (( string ) $ setting [ ' description ' ] )]),
241
+ new InlineCompoundNode ([new PlainTextInlineNode ($ description )]),
192
242
]);
193
243
}
194
244
$ default = null ;
195
245
if (($ setting ['default ' ] ?? '' ) !== '' ) {
196
246
$ default = new InlineCompoundNode ([new CodeInlineNode ($ this ->customPrint (($ setting ['default ' ])), '' )]);
197
247
}
198
248
$ additionalFields = [];
199
- if (is_string ($ setting ['label ' ] ?? false )) {
200
- $ additionalFields ['Label ' ] = new InlineCompoundNode ([new PlainTextInlineNode ($ setting ['label ' ] ?? '' )]);
249
+ $ label = $ setting ['label ' ] ?? $ labels [$ key ] ?? false ;
250
+ if (is_string ($ label )) {
251
+ $ additionalFields ['Label ' ] = new InlineCompoundNode ([new PlainTextInlineNode ($ label )]);
201
252
}
202
253
if (is_array ($ setting ['enum ' ] ?? false )) {
203
254
$ additionalFields ['Enum ' ] = new InlineCompoundNode ([new PlainTextInlineNode ((string ) json_encode ($ setting ['enum ' ], JSON_PRETTY_PRINT ))]);
0 commit comments