Skip to content

Commit 3c80aa6

Browse files
feat: add support for Scalar UI (#2711)
## Description Adds support for https://scalar.com as an alternative API documentation UI renderer, alongside the existing SwaggerUI, Redocly, and Stoplight Elements options. What's included: - New scalar renderer constant in Renderer.php - scalar_config configuration node to pass https://scalar.com/products/api-references/configuration - Dedicated Twig template (templates/Scalar/index.html.twig) with bundled standalone JS - New routing file (config/routing/scalar.php) for serving the Scalar UI - Service definition for the Scalar controller - Documentation update in docs/configuration_reference.rst Closes #... ## What type of PR is this? (check all applicable) - [ ] Bug Fix - [x] Feature - [ ] Refactor - [ ] Deprecation - [ ] Breaking Change - [ ] Documentation Update - [ ] CI ## Checklist - [x] I have made corresponding changes to the documentation (`docs/`) --------- Co-authored-by: djordy <djordy.koert@yoursurprise.com>
1 parent b5d5e1f commit 3c80aa6

14 files changed

Lines changed: 45480 additions & 2 deletions

File tree

.github/workflows/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ jobs:
2727
run: yarn run swagger
2828
- name: Redocly
2929
run: yarn run redoc
30+
- name: Scalar
31+
run: yarn run scalar
32+
- name: Stoplight
33+
run: yarn run stoplight
3034
- uses: stefanzweifel/git-auto-commit-action@v7
3135
with:
3236
commit_message: "[dependabot-skip] Update UI files"

config/routing/scalar.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the NelmioApiDocBundle package.
7+
*
8+
* (c) Nelmio
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
16+
17+
return static function (RoutingConfigurator $routes): void {
18+
$routes->add('nelmio_api_doc.scalar', '/')
19+
->controller('nelmio_api_doc.controller.scalar')
20+
->methods([Request::METHOD_GET]);
21+
};

config/services.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
'redocly',
3434
])
3535

36+
->set('nelmio_api_doc.controller.scalar', \Nelmio\ApiDocBundle\Controller\SwaggerUiController::class)
37+
->public()
38+
->args([
39+
service('nelmio_api_doc.render_docs'),
40+
'scalar',
41+
])
42+
3643
->set('nelmio_api_doc.controller.stoplight', \Nelmio\ApiDocBundle\Controller\SwaggerUiController::class)
3744
->public()
3845
->args([

docs/configuration_reference.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ The bundle configuration is stored under the ``nelmio_api_doc`` key in your appl
4242
swagger_ui_config: []
4343
# https://redocly.com/docs/redoc/config/
4444
redocly_config: []
45+
# https://scalar.com/products/api-references/configuration
46+
scalar_config: []
4547
# https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options
4648
stoplight_config: []
4749
# Filter the routes that are documented

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ parameters:
2727
-
2828
message: '#^Call to method render\(\) on an unknown class Twig_Environment\.$#'
2929
identifier: class.notFound
30-
count: 3
30+
count: 4
3131
path: src/Render/Html/HtmlOpenApiRenderer.php
3232

3333
-

public/scalar/scalar.standalone.js

Lines changed: 45371 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DependencyInjection/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public function getConfigTreeBuilder(): TreeBuilder
9797
->addDefaultsIfNotSet()
9898
->ignoreExtraKeys(false)
9999
->end()
100+
->arrayNode('scalar_config')
101+
->info('https://scalar.com/products/api-references/configuration')
102+
->addDefaultsIfNotSet()
103+
->ignoreExtraKeys(false)
104+
->end()
100105
->arrayNode('stoplight_config')
101106
->info('https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options')
102107
->addDefaultsIfNotSet()

src/Render/Html/HtmlOpenApiRenderer.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ public function render(OpenApi $spec, array $options = []): string
5151
);
5252
}
5353

54+
if (isset($options['ui_renderer']) && Renderer::SCALAR === $options['ui_renderer']) {
55+
return $this->twig->render(
56+
'@NelmioApiDoc/Scalar/index.html.twig',
57+
[
58+
'swagger_data' => ['spec' => json_decode($spec->toJson(), true)],
59+
'assets_mode' => $options['assets_mode'],
60+
'scalar_config' => $options['scalar_config'],
61+
]
62+
);
63+
}
64+
5465
if (isset($options['ui_renderer']) && Renderer::STOPLIGHT === $options['ui_renderer']) {
5566
return $this->twig->render(
5667
'@NelmioApiDoc/Stoplight/index.html.twig',

src/Render/Html/Renderer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ class Renderer
1515
{
1616
public const REDOCLY = 'redocly';
1717
public const SWAGGERUI = 'swaggerui';
18+
public const SCALAR = 'scalar';
1819
public const STOPLIGHT = 'stoplight';
1920
}

templates/Scalar/index.html.twig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
{% block meta %}
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7+
{% endblock meta %}
8+
<title>{% block title %}{{ swagger_data.spec.info.title }}{% endblock title %}</title>
9+
</head>
10+
<body>
11+
{% block swagger_ui %}
12+
<script id="api-reference" type="application/json">{{ swagger_data.spec|json_encode(65)|raw }}</script>
13+
{% endblock swagger_ui %}
14+
{% block swagger_initialization %}
15+
{% if scalar_config is not empty %}
16+
<script>
17+
document.getElementById('api-reference').dataset.configuration = JSON.stringify({{ scalar_config|json_encode(65)|raw }});
18+
</script>
19+
{% endif %}
20+
{{ nelmioAsset(assets_mode, 'scalar/scalar.standalone.js') }}
21+
{% endblock swagger_initialization %}
22+
</body>
23+
</html>

0 commit comments

Comments
 (0)