Theming
note
The theming system is still experimental. It won't change significantly, but we're looking for ways to make it simpler and more consistent. We're open to your suggestions!
Scribe v3 comes with support for themes, allowing you to customize how your docs look. Scribe currently only comes with one theme, default
, but you can create a new theme. Let's see how.
Anatomy of a theme
A theme consists of:
- an
index.blade.php
file that takes the API details and renders to HTML. For custom themes, this file has to be inresources/views/vendor/scribe/themes/{themeName}/
. - any accompanying CSS and JS files. You can place these anywhere in your codebase, as long as you reference them correctly from the theme file (keeping in mind the actual path your docs/ page will be visited from).
When you run php artisan scribe:generate
, Scribe will use the theme template to generate the HTML. For inbuilt themes, it will also copy any CSS and JS files to your app's public directory. For custom themes, you'll have to manage that part yourself.
Creating a new theme
To create a new theme (let's call this theme nasty
), place the index.blade.php
in resources/views/vendor/scribe/themes/nasty/
. Next, we change the value of theme
in our config:
'theme' => 'nasty',
Now we write the theme. Writing a theme file can be a lot of work, so we recommend using the default theme as a starting point. Here's a very simple theme file:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{!! $metadata['title'] !!}</title>
<link rel="stylesheet" href="../docs/css/nasty.css">
<link rel="stylesheet"
href="//unpkg.com/@highlightjs/cdn-assets@10.7.2/styles/obsidian.min.css">
<script src="//unpkg.com/@highlightjs/cdn-assets@10.7.2/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<div class="content">
{!! $intro !!}
{!! $auth !!}
@include("scribe::themes.default.groups")
</div>
</body>
</html>
Our theme file is a regular Blade/HTML page. We can do whatever we wish in here, and use Blade constructs as normal. Let's see what's going on here:
First, we're using the $metadata
object that's passed to our theme. This object has the following structure:
[
'title' => 'The title of the API',
'example_languages' => ['bash', 'javascript'], // Your `example_languages` config
'logo' => 'logo_url', // Your `logo` config
'last_updated' => '2021-09-12', // Current date string
'auth' => [
'location' => 'header', // or 'query', or 'body'
'prefix' => 'Bearer ', // or 'Basic ' or ''
// Plus the rest of your `auth` config
],
'try_it_out' => [ // Your `try_it_out` config
'enabled' => true,
'base_url' => '',
]
// List of HTML links to be placed at the bottom of the sidebar (including Postman collection and OpenAPI links)
'links' => ['<a href="http://github.com/knuckleswtf/scribe">Documentation powered by Scribe ✍</a>'],
]
Next, we reference a stylesheet, nasty.css
, which we've placed in our public/docs
folder, as well as the highlight.js CSS and JS for syntax highlighting.
Then, in the <body>
, we output the $index
and $auth
information. Those variables hold basic HTML containing the text for the introduction and authentication sections.
In addition to these variables, the theme file has access to the following variables:
$baseUrl
: the base URL to be displayed in the docs$tryItOut
: thetry_it_out
section from your config file$append
: the HTMl from any.scribe/append.md
file added by the user$groupedEndpoints
: the endpoints in the API, organized by groups. Each item in this array is an array with the following shape:[
'name' => 'The group name',
'description' => 'The description',
'endpoints' => [
// Array of Knuckles\Camel\Output\OutputEndpointData
]
]
Finally, you'll notice that at the end, we include "scribe::themes.default.groups"
. This means our theme just changed the outer page structure, and falls back to the default theme to render the actual endpoints and groups. This is a great way to modify an existing theme. If we wanted to create a totally new theme, then we would replace the include directive with our own custom Blade that would loop over the groups and render endpoints.
Now when you run php artisan scribe:generate
, Laravel will load your custom theme instead of the default.
If you need a starting point or more guidance to create your own theme, you should look at the included theme files.
tip
The Knuckles\Scribe\Tools\WritingUtils
class contains some helpful utilities that might save you some work; for instance, printing query parameters as a key-value hash.
Customising all templates
If you really want to customise all the templates Scribe uses for generating, you can publish the vendor views:
- Laravel
- Lumen
Run:
php artisan vendor:publish --tag=scribe-views
- Create the
resources/views/vendor/scribe/
directory in your app - Copy the contents of
vendor/knuckleswtf/scribe/resources/views/
into it.
When you do this, your resources/views/vendor/scribe/
folder should have this structure:
components/
|-- badges/
|-- base.blade.php
|-- auth.blade.php
|-- http-method.blade.php
|-- body-parameters.blade.php
|-- field-details.blade.php
markdown/
|-- intro.blade.php
|-- auth.blade.php
partials/
|-- example-requests/
|-- bash.md.blade.php
|-- javascript.md.blade.php
|-- php.md.blade.php
|-- python.md.blade.php
themes/
|-- default/
|-- index.blade.php
|-- groups.blade.php
|-- endpoint.blade.php
The components
folder contains some Blade components used in the themes. For instance, you can display a badge using the base.blade.php
component:
@component('scribe::components.badges.base', [
'colour' => "darkred",
'text' => 'requires authentication'
])
The partials
folder contains the example request templates. If you want these alone, you can run php artisan vendor:publish --tag=scribe-examples
instead.
The markdown
folder contains the templates for the intermediate Markdown files that will be generated in your .scribe
folder (index.md
, and auth.md
). If you want these alone, you can run php artisan vendor:publish --tag=scribe-markdown
instead.
- In the
intro.blade.php
, you have access to: -$description
(the API description),$introText
(the text for the introductory section), and$baseUrl
(the URL to be displayed in the docs).
- In the
auth.blade.php
file, you have$isAuthed
(true
if the API has auth enabled),$authDescription
(generated by Scribe from yourauth
config), and$extraAuthInfo
(theauth.extra_info
section in your config)
The themes
folder contains the templates for the included themes. If you want these alone, you can run php artisan vendor:publish --tag=scribe-themes
instead.