29 |
30 |
31 | {actions -> f:format.raw()}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ```
40 |
41 | For further instructions on how to build components, please refer to the [documentation of Fluid Components](https://github.com/sitegeist/fluid-components).
42 |
43 | ## Adding fixtures to your component
44 |
45 | Each component in the styleguide needs a fixture file which contains example values for all of the component's required arguments.
46 | A fixture file must at least contain a `default` fixture, but it may define additional fixtures that can then be selected
47 | in the styleguide interface.
48 |
49 | A fixture can be created in `.php`, `.json`, [`.json5`](https://json5.org/), `.yml` or `.yaml` files. You should create only one fixture file per
50 | component. The styleguide takes the first fixture file and ignores eventually existing files in other formats in the following order:
51 |
52 | 1. `.php`
53 | 2. `.json`
54 | 3. `.json5`
55 | 4. `.yml`
56 | 5. `.yaml`
57 |
58 | Support for `json5` only works if you install the fluid-styleguide with composer (not by TER!).
59 |
60 | **Molecule/Teaser/Teaser.fixture.php:**
61 |
62 | ```php
63 | return [
64 | 'default' => [
65 | 'title' => 'TYPO3',
66 | 'link' => 'https://typo3.org',
67 | ],
68 | 'dark' => [
69 | 'title' => 'TYPO3',
70 | 'link' => 'https://typo3.org',
71 | 'theme' => 'dark',
72 | ],
73 | ];
74 | ```
75 |
76 | or **Molecule/Teaser/Teaser.fixture.json:**
77 |
78 | ```json
79 | {
80 | "default": {
81 | "title": "TYPO3",
82 | "link": "https://typo3.org"
83 | },
84 | "dark": {
85 | "title": "TYPO3",
86 | "link": "https://typo3.org",
87 | "theme": "dark"
88 | }
89 | }
90 | ```
91 |
92 | or **Molecule/Teaser/Teaser.fixture.json5:**
93 |
94 | ```json5
95 | {
96 | // can contain comments
97 | "default": {
98 | "title": "TYPO3 \
99 | can contain multiline strings",
100 | "link": "https://typo3.org"
101 | },
102 | "dark": {
103 | "title": 'TYPO3 with single quotes',
104 | "link": "https://typo3.org",
105 | "theme": "dark"
106 | }
107 | }
108 | ```
109 |
110 | or **Molecule/Teaser/Teaser.fixture.yaml:**
111 |
112 | ```yaml
113 | default:
114 | title: |
115 | TYPO3
116 | Multiline
117 | link: https://typo3.org
118 | dark:
119 | title: TYPO3
120 | link: https://typo3.org
121 | theme: dark
122 | ```
123 |
124 | File naming scheme: *{ComponentName}.fixture.[php|json|[json5](https://json5.org/)|yml|yaml]*
125 |
126 | You can define the content of a component if the component supports it:
127 |
128 | ```json
129 | {
130 | "default": {
131 | "content": "The professional, flexible Content Management System"
132 | }
133 | }
134 | ```
135 |
136 | You can use fluid in your fixture data to nest components (as long as the Fluid namespace [is defined globally](https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/8.5/Feature-78415-GlobalFluidViewHelperNamespacesMovedToTYPO3Configuration.html)):
137 |
138 | ```json
139 | {
140 | "default": {
141 | "actions": "Primary ButtonSecondary Button"
142 | }
143 | }
144 | ```
145 |
146 | You can use [data structures with argument converters](https://github.com/sitegeist/fluid-components/blob/master/Documentation/DataStructures.md) to define placeholder images and advanced links:
147 |
148 | ```json
149 | {
150 | "default": {
151 | "image": {
152 | "height": 300,
153 | "width": 500,
154 | "alternative": "My alt text",
155 | "title": "My image title"
156 | },
157 | "link": {
158 | "uri": "https://typo3.org",
159 | "target": "_blank"
160 | }
161 | }
162 | }
163 | ```
164 |
165 | You can provide a label for each fixture:
166 |
167 | ```json
168 | "onDarkBackground": {
169 | "styleguideFixtureLabel": "On dark background",
170 | },
171 | ```
172 |
173 | You can override the default [component context](./ConfigurationReference.md) for each fixture:
174 |
175 | ```json
176 | {
177 | "onDarkBackground": {
178 | "styleguideComponentContext": "
|
"
179 | }
180 | }
181 | ```
182 |
183 | ## Adding documentation to your component
184 |
185 | If you want to add further documentation to your component, just place a markdown file that is named like your component
186 | inside your component folder. Fluid Styleguide will pick up the documentation automatically and render it in the DOC tab.
187 |
188 | **Molecule/Teaser/Teaser.md:**
189 |
190 | ```markdown
191 | ## Teaser Component
192 |
193 | This is a generic teaser components. It supports both a light and a dark styling. [...]
194 | ```
195 |
196 | File naming scheme: *{ComponentName}.md*
197 |
--------------------------------------------------------------------------------
/Classes/Domain/Model/Component.php:
--------------------------------------------------------------------------------
1 | name;
29 | }
30 |
31 | public function getLocation(): ComponentLocation
32 | {
33 | return $this->location;
34 | }
35 |
36 | public function getFixtureFile(): string
37 | {
38 | $fixtureFilesToSearch = [
39 | '.fixture.php',
40 | '.fixture.json',
41 | '.fixture.yml',
42 | '.fixture.yaml'
43 | ];
44 | if (Environment::isComposerMode()) {
45 | $fixtureFilesToSearch[] = '.fixture.json5';
46 | }
47 |
48 | foreach ($fixtureFilesToSearch as $fixtureFile) {
49 | $path = $this->location->generatePathToFile($this->name->getSimpleName() . $fixtureFile);
50 | if (file_exists($path)) {
51 | return $path;
52 | }
53 | }
54 | // fallback to .json
55 | return $this->location->generatePathToFile($this->name->getSimpleName() . '.fixture.json');
56 | }
57 |
58 | public function hasFixtures(): bool
59 | {
60 | return file_exists($this->getFixtureFile());
61 | }
62 |
63 | public function getFixtures(): array
64 | {
65 | if (isset($this->fixtures)) {
66 | return $this->fixtures;
67 | }
68 |
69 | if (!$this->hasFixtures()) {
70 | return $this->fixtures;
71 | }
72 |
73 | $fixtureFile = $this->getFixtureFile();
74 | $fileParts = pathinfo((string) $fixtureFile);
75 | switch ($fileParts['extension']) {
76 | case 'json':
77 | $fixtures = \json_decode(file_get_contents($fixtureFile), true) ?? [];
78 | break;
79 | case 'json5':
80 | if (function_exists('json5_decode')) {
81 | $fixtures = \json5_decode(file_get_contents($fixtureFile), true) ?? [];
82 | } else {
83 | $fixtures = [];
84 | }
85 | break;
86 | case 'yaml':
87 | case 'yml':
88 | $loader = GeneralUtility::makeInstance(YamlFileLoader::class);
89 | $fixtures = $loader->load($fixtureFile) ?? [];
90 | break;
91 | case 'php':
92 | $fixtures = require $fixtureFile;
93 | break;
94 | default:
95 | throw new \Exception('Fixture format unknown', 1582196195);
96 | }
97 | if (!is_array($fixtures)) {
98 | throw new \InvalidArgumentException('Fixtures must be of type array', 1738326135);
99 | }
100 | if (!isset($fixtures['default'])) {
101 | $fixtures['default'] = [];
102 | }
103 | foreach ($fixtures as $fixtureName => $fixtureData) {
104 | $this->fixtures[$fixtureName] = new ComponentFixture(
105 | $fixtureFile,
106 | $fixtureName,
107 | $fixtureData
108 | );
109 | }
110 |
111 | return $this->fixtures;
112 | }
113 |
114 | public function getFixture(string $name): ?ComponentFixture
115 | {
116 | return $this->getFixtures()[$name] ?? null;
117 | }
118 |
119 | public function getDocumentationFile(): string
120 | {
121 | return $this->location->generatePathToFile($this->name->getSimpleName() . '.md');
122 | }
123 |
124 | public function hasDocumentation(): bool
125 | {
126 | return file_exists($this->getDocumentationFile());
127 | }
128 |
129 | public function getDocumentation(): string
130 | {
131 | if (!isset($this->documentation)) {
132 | if ($this->hasDocumentation()) {
133 | $this->documentation = file_get_contents($this->getDocumentationFile());
134 | } else {
135 | $this->documentation = '';
136 | }
137 | }
138 |
139 | return $this->documentation;
140 | }
141 |
142 | public function getArguments(): array
143 | {
144 | if (!isset($this->arguments)) {
145 | $this->arguments = $this->getComponentRenderer()->prepareArguments();
146 | }
147 |
148 | return $this->arguments;
149 | }
150 |
151 | public function getDefaultValues(): array
152 | {
153 | return array_reduce($this->getArguments(), function ($defaults, $argument) {
154 | if (!$argument->isRequired()) {
155 | $defaults[$argument->getName()] = $argument->getDefaultValue();
156 | }
157 | return $defaults;
158 | }, []);
159 | }
160 |
161 | public function getCodeQualityConfiguration(): ?string
162 | {
163 | $configurationFileLocations = [
164 | $this->getLocation()->getDirectory(),
165 | $this->getName()->getPackage()->getPath(),
166 | rtrim($this->getName()->getPackage()->getExtension()->getPackagePath(), DIRECTORY_SEPARATOR)
167 | ];
168 | foreach ($configurationFileLocations as $configurationFileLocation) {
169 | $configurationFile = $configurationFileLocation . DIRECTORY_SEPARATOR . '.fclint.json';
170 | if (file_exists($configurationFile)) {
171 | return $configurationFile;
172 | }
173 | }
174 | return null;
175 | }
176 |
177 | protected function getComponentRenderer(): ComponentRenderer
178 | {
179 | $componentRenderer = GeneralUtility::makeInstance(ComponentRenderer::class);
180 | $componentRenderer->setComponentNamespace($this->name->getIdentifier());
181 | return $componentRenderer;
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/Documentation/ConfigurationReference.md:
--------------------------------------------------------------------------------
1 | # Fluid Styleguide Configuration Reference
2 |
3 | Fluid Styleguide can be configured in various ways by creating a YAML configuration file in your extension or sitepackage:
4 |
5 | **Configuration/Yaml/FluidStyleguide.yaml**
6 |
7 | Each extension can add its own configuration to the styleguide, all available files will be picked up automatically and merged with the [default configuration file](../Configuration/Yaml/FluidStyleguide.yaml).
8 |
9 | ## Adding frontend assets
10 |
11 | Each component package (= a folder containing multiple components in a directory structure) usually brings its own frontend assets
12 | that define the design (CSS) and behavior (JavaScript) of the components.
13 |
14 | Assets can be defined per component package:
15 |
16 | ```yaml
17 | FluidStyleguide:
18 | ComponentAssets:
19 | Packages:
20 | 'Vendor\MyExtension\Components':
21 | Css:
22 | - EXT:my_extension/Resources/Public/Css/Components.css
23 | Javascript:
24 | - EXT:my_extension/Resources/Public/Javascript/Components.js
25 | ```
26 |
27 | Assets can also be added globally:
28 |
29 | ```yaml
30 | FluidStyleguide:
31 | ComponentAssets:
32 | Global:
33 | Css:
34 | - EXT:my_extension/Resources/Public/Css/Global.css
35 | Javascript:
36 | - EXT:my_extension/Resources/Public/Javascript/Global.min.js
37 | ```
38 |
39 | For JavaScript assets, you can define if they should be added to the `` or to the
40 | bottom of the page (which is the default):
41 |
42 | ```yaml
43 | FluidStyleguide:
44 | ComponentAssets:
45 | Global:
46 | Javascript:
47 | -
48 | file: EXT:my_extension/Resources/Public/Javascript/Global.min.js
49 | position: head
50 | ```
51 |
52 | ## Modifying the component context
53 |
54 | While most components can function without a specific context around them, for
55 | some components their context is quite important. For example, a button component
56 | could have a special styling when used on dark backgrounds. In this case the styleguide
57 | should use a dark background as well when this variant of the button is displayed.
58 |
59 | By default, Fluid Styleguide uses the following component context, which adds
60 | a 24px space around each component:
61 |
62 | ```yaml
63 | FluidStyleguide:
64 | # Markup that will be wrapped around the component output in the styleguide
65 | # This can be overwritten per component fixture by specifying
66 | # "styleguideComponentContext" in the fixture data
67 | ComponentContext: '
|
'
68 | ```
69 |
70 | Fluid markup is supported in the component context, which means that you can wrap
71 | your components in other components in the styleguide. Every pipe character within
72 | the specified context markup will be replaced with the component markup.
73 |
74 | This context can be modified either globally in your FluidStyleguide.yaml or
75 | individually for each variant of a component in the appropriate fixture file:
76 |
77 | Button.fixture.json:
78 |
79 | ```json
80 | {
81 | "default": {
82 | ...
83 | },
84 | "onDarkBackground": {
85 | ...
86 | "styleguideComponentContext": "