Search code examples
reactjslaravelswaggerswagger-uidarkaonlinel5-swagger

How to use my custom Layout for Swagger UI in DarkaOnLine / L5-Swagger in Laravel 9


I am trying to use Custom Layouts for the L5-Swagger Laravel package. But every time I try inputting "OperationsLayout" in "plugins" it gives it doesn't exist error. How would I use it in this context? Here is the code in question:

<body>
<div id="swagger-ui"></div>

<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
<script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>

<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

<script type="text/babel">
    import React from "react"

    // Create the layout component
    class OperationsLayout extends React.Component {
        render() {
            const {
                getComponent
            } = this.props
            const Operations = getComponent("operations", true)
            return (
                <div>
                    <Operations />
                </div>
            )
        }
    }

    // Create the plugin that provides our layout component
    const OperationsLayoutPlugin = () => {
        return {
            components: {
                OperationsLayout: OperationsLayout
            }
        }
    }

    // Provide the plugin to Swagger-UI, and select OperationsLayout
    // as the layout for Swagger-UI
    SwaggerUIBundle({
        url: "{!! $urlToDocs !!}",
        plugins: [ OperationsLayoutPlugin ],
        layout: "OperationsLayout"
    })
</script>

<script>
    window.onload = function() {
        // Build a system
        const ui = SwaggerUIBundle({
            dom_id: '#swagger-ui',
            url: "{!! $urlToDocs !!}",
            operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
            configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
            validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
            oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",

            requestInterceptor: function(request) {
                request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
                return request;
            },

            presets: [
                SwaggerUIBundle.presets.apis,
                SwaggerUIStandalonePreset
            ],

            plugins: [
                SwaggerUIBundle.plugins.DownloadUrl
            ],

            layout: "StandaloneLayout",
            docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
            deepLinking: true,
            filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
            persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",

        })

        window.ui = ui
    }
</script>
</body>

How would I get the second script tag to grab my OperationsLayout?

What I have tried: I tried to use localStorage to see maybe I could have grab the class variable and plugin variable be accessible to the second js inline part of the code.


Solution

  • Thanks to Helen for pointing this out.

    Here is how I did it.

    I added the babel CDN, then combined my inline scripts into one.

    Lastly for type I added "text/babel".

    That's it guys! You can now follow Swagger's documentation and work within L5-Swagger's index.blade.php file.

    Here is the code:

    <div id="swagger-ui"></div>
    
    <script src="{{ l5_swagger_asset($documentation, 'swagger-ui-bundle.js') }}"></script>
    <script src="{{ l5_swagger_asset($documentation, 'swagger-ui-standalone-preset.js') }}"></script>
    
    <!-- Load React. -->
    <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    
    <script type="text/babel">
        // Create the layout component
        class SidebarLayout extends React.Component {
            render() {
                const {
                    getComponent
                } = this.props
                const StandaloneLayout = getComponent("StandaloneLayout", true)
                const Operations = getComponent("operations", true)
                return (
                    <div>
                        <StandaloneLayout />
                    </div>
                )
            }
        }
        
        // Create the plugin that provides our layout component
        const SidebarLayoutPlugin = () => {
            return {
                components: {
                    SidebarLayout: SidebarLayout
                }
            }
        }
    
        window.onload = function() {
            // Build a system
            const ui = SwaggerUIBundle({
                dom_id: '#swagger-ui',
                url: "{!! $urlToDocs !!}",
                operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
                configUrl: {!! isset($configUrl) ? '"' . $configUrl . '"' : 'null' !!},
                validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
                oauth2RedirectUrl: "{{ route('l5-swagger.'.$documentation.'.oauth2_callback', [], $useAbsolutePath) }}",
    
                requestInterceptor: function(request) {
                    request.headers['X-CSRF-TOKEN'] = '{{ csrf_token() }}';
                    return request;
                },
    
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset
                ],
    
                plugins: [
                    SidebarLayoutPlugin,
                    SwaggerUIBundle.plugins.DownloadUrl
                ],
    
                layout: "SidebarLayout",
                docExpansion : "{!! config('l5-swagger.defaults.ui.display.doc_expansion', 'none') !!}",
                deepLinking: true,
                filter: {!! config('l5-swagger.defaults.ui.display.filter') ? 'true' : 'false' !!},
                persistAuthorization: "{!! config('l5-swagger.defaults.ui.authorization.persist_authorization') ? 'true' : 'false' !!}",
    
            })
    
            window.ui = ui
        }
    </script>