mirror of
https://github.com/ambieco/scribe.git
synced 2026-03-26 14:14:05 +08:00
Implement custom translation layer
This commit is contained in:
34
lang/en.json
34
lang/en.json
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"scribe::auth.instruction.query": "To authenticate requests, include a query parameter **`:parameterName`** in the request.",
|
||||
"scribe::auth.instruction.body": "To authenticate requests, include a parameter **`:parameterName`** in the body of the request.",
|
||||
"scribe::auth.instruction.query_or_body": "To authenticate requests, include a parameter **`:parameterName`** either in the query string or in the request body.",
|
||||
"scribe::auth.instruction.bearer": "To authenticate requests, include an **`Authorization`** header with the value **`\"Bearer :placeholder\"`**.",
|
||||
"scribe::auth.instruction.basic": "To authenticate requests, include an **`Authorization`** header in the form **`\"Basic {credentials}\"`**. The value of `{credentials}` should be your username/id and your password, joined with a colon (:), and then base64-encoded.",
|
||||
"scribe::auth.instruction.header": "To authenticate requests, include a **`:parameterName`** header with the value **`\":placeholder\"`**.",
|
||||
"scribe::auth.details": "All authenticated endpoints are marked with a `requires authentication` badge in the documentation below.",
|
||||
"scribe::search": "Search",
|
||||
"scribe::base_url": "Base URL",
|
||||
"scribe::headers.introduction": "Introduction",
|
||||
"scribe::headers.auth": "Authenticating requests",
|
||||
"scribe::no_auth": "This API is not authenticated.",
|
||||
"scribe::example_request": "Example request",
|
||||
"scribe::example_response": "Example response",
|
||||
"scribe::example_response.binary": "Binary data",
|
||||
"scribe::example_response.empty": "Empty response",
|
||||
"scribe::endpoint.request": "Request",
|
||||
"scribe::endpoint.headers": "Headers",
|
||||
"scribe::endpoint.url_parameters": "URL Parameters",
|
||||
"scribe::endpoint.body_parameters": "Body Parameters",
|
||||
"scribe::endpoint.query_parameters": "Query Parameters",
|
||||
"scribe::endpoint.response": "Response",
|
||||
"scribe::endpoint.response_fields": "Response Fields",
|
||||
"scribe::try_it_out.open": "Try it out ⚡",
|
||||
"scribe::try_it_out.cancel": "Cancel 🛑",
|
||||
"scribe::try_it_out.send": "Send Request 💥",
|
||||
"scribe::try_it_out.loading": "⏱ Sending...",
|
||||
"scribe::try_it_out.received_response": "Received response",
|
||||
"scribe::try_it_out.request_failed": "Request failed with error",
|
||||
"scribe::try_it_out.error_help": "Tip: Check that you're properly connected to the network.\nIf you're a maintainer of ths API, verify that your API is running and you've enabled CORS.\nYou can check the Dev Tools console for debugging information.",
|
||||
"scribe::links.postman": "View Postman collection",
|
||||
"scribe::links.openapi": "View OpenAPI spec"
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
@php
|
||||
use Knuckles\Scribe\Tools\Utils as u;
|
||||
@endphp
|
||||
# {{ u::trans("scribe::headers.auth") }}
|
||||
# {{ u::trans("scribe::headings.auth") }}
|
||||
|
||||
@if(!$isAuthed)
|
||||
{!! u::trans("scribe::no_auth") !!}
|
||||
{!! u::trans("scribe::auth.none") !!}
|
||||
@else
|
||||
{!! $authDescription !!}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@php
|
||||
use Knuckles\Scribe\Tools\Utils as u;
|
||||
@endphp
|
||||
# {{ u::trans("scribe::headers.introduction") }}
|
||||
# {{ u::trans("scribe::headings.introduction") }}
|
||||
|
||||
{!! $description !!}
|
||||
|
||||
<aside>
|
||||
<strong>{{ u::trans("scribe::base_url") }}</strong>: <code>{!! $baseUrl !!}</code>
|
||||
<strong>{{ u::trans("scribe::labels.base_url") }}</strong>: <code>{!! $baseUrl !!}</code>
|
||||
</aside>
|
||||
|
||||
{!! $introText !!}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{!! Parsedown::instance()->text($endpoint->metadata->description ?: '') !!}
|
||||
|
||||
<span id="example-requests-{!! $endpoint->endpointId() !!}">
|
||||
<blockquote>{{ u::trans("scribe::example_request") }}:</blockquote>
|
||||
<blockquote>{{ u::trans("scribe::endpoint.example_request") }}:</blockquote>
|
||||
|
||||
@foreach($metadata['example_languages'] as $language)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
@if($endpoint->isGet() || $endpoint->hasResponses())
|
||||
@foreach($endpoint->responses as $response)
|
||||
<blockquote>
|
||||
<p>{{ u::trans("scribe::example_response") }} ({{ $response->fullDescription() }}):</p>
|
||||
<p>{{ u::trans("scribe::endpoint.example_response") }} ({{ $response->fullDescription() }}):</p>
|
||||
</blockquote>
|
||||
@if(count($response->headers))
|
||||
<details class="annotation">
|
||||
@@ -40,9 +40,9 @@
|
||||
@endforeach </code></pre></details> @endif
|
||||
<pre>
|
||||
@if(is_string($response->content) && Str::startsWith($response->content, "<<binary>>"))
|
||||
<code>{!! u::trans("scribe::example_response.binary") !!} - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code>
|
||||
<code>{!! u::trans("scribe::endpoint.responses.binary") !!} - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code>
|
||||
@elseif($response->status == 204)
|
||||
<code>{!! u::trans("scribe::example_response.empty") !!}</code>
|
||||
<code>{!! u::trans("scribe::endpoint.responses.empty") !!}</code>
|
||||
@else
|
||||
@php($parsed = json_decode($response->content))
|
||||
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
|
||||
@@ -56,7 +56,7 @@
|
||||
id="execution-response-status-{{ $endpoint->endpointId() }}"></span>:
|
||||
</blockquote>
|
||||
<pre class="json"><code id="execution-response-content-{{ $endpoint->endpointId() }}"
|
||||
data-empty-response-text="<{{ u::trans("scribe::example_response.empty") }}>" style="max-height: 400px;"></code></pre>
|
||||
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>" style="max-height: 400px;"></code></pre>
|
||||
</span>
|
||||
<span id="execution-error-{{ $endpoint->endpointId() }}" hidden>
|
||||
<blockquote>{{ u::trans("scribe::try_it_out.request_failed") }}:</blockquote>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
@endisset
|
||||
|
||||
<div class="search">
|
||||
<input type="text" class="search" id="input-search" placeholder="{{ u::trans("scribe::search") }}">
|
||||
<input type="text" class="search" id="input-search" placeholder="{{ u::trans("scribe::labels.search") }}">
|
||||
</div>
|
||||
|
||||
<div id="toc">
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<div class="sl-panel__titlebar sl-flex sl-items-center sl-relative focus:sl-z-10 sl-text-base sl-leading-none sl-pr-3 sl-pl-4 sl-bg-canvas-200 sl-text-body sl-border-input focus:sl-border-primary sl-select-none">
|
||||
<div class="sl-flex sl-flex-1 sl-items-center sl-h-lg">
|
||||
<div class="sl--ml-2">
|
||||
{{ u::trans("scribe::example_request") }}:
|
||||
{{ u::trans("scribe::endpoint.example_request") }}:
|
||||
<select class="example-request-lang-toggle sl-text-base"
|
||||
aria-label="Request Sample Language"
|
||||
onchange="switchExampleLanguage(event.target.value);">
|
||||
@@ -188,7 +188,7 @@
|
||||
<div class="sl-flex sl-flex-1 sl-items-center sl-py-2">
|
||||
<div class="sl--ml-2">
|
||||
<div class="sl-h-sm sl-text-base sl-font-medium sl-px-1.5 sl-text-muted sl-rounded sl-border-transparent sl-border">
|
||||
<div class="sl-mb-2 sl-inline-block">{{ u::trans("scribe::example_response") }}:</div>
|
||||
<div class="sl-mb-2 sl-inline-block">{{ u::trans("scribe::endpoint.example_response") }}:</div>
|
||||
<div class="sl-mb-2 sl-inline-block">
|
||||
<select
|
||||
class="example-response-{{ $endpoint->endpointId() }}-toggle sl-text-base"
|
||||
@@ -241,9 +241,9 @@
|
||||
</details>
|
||||
@endif
|
||||
@if(is_string($response->content) && Str::startsWith($response->content, "<<binary>>"))
|
||||
<pre><code>[{{ u::trans("scribe::example_response.binary") }}] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code></pre>
|
||||
<pre><code>[{{ u::trans("scribe::endpoint.responses.binary") }}] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code></pre>
|
||||
@elseif($response->status == 204)
|
||||
<pre><code>[{{ u::trans("scribe::example_response.empty") }}]</code></pre>
|
||||
<pre><code>[{{ u::trans("scribe::endpoint.responses.empty") }}]</code></pre>
|
||||
@else
|
||||
@php($parsed = json_decode($response->content))
|
||||
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
<div class="sl-panel__content sl-p-4">
|
||||
<p class="sl-pb-2 response-status"></p>
|
||||
<pre><code class="sl-pb-2 response-content language-json"
|
||||
data-empty-response-text="<{{ u::trans("scribe::example_response.empty") }}>"
|
||||
data-empty-response-text="<{{ u::trans("scribe::endpoint.responses.empty") }}>"
|
||||
style="max-height: 300px;"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@ use Knuckles\Scribe\Matching\RouteMatcher;
|
||||
use Knuckles\Scribe\Matching\RouteMatcherInterface;
|
||||
use Knuckles\Scribe\Tools\BladeMarkdownEngine;
|
||||
use Knuckles\Scribe\Tools\Utils;
|
||||
use Knuckles\Scribe\Writing\CustomTranslationsLoader;
|
||||
|
||||
class ScribeServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -24,10 +25,7 @@ class ScribeServiceProvider extends ServiceProvider
|
||||
|
||||
$this->registerCommands();
|
||||
|
||||
$this->loadJsonTranslationsFrom(__DIR__.'/../lang');
|
||||
$this->publishes([
|
||||
__DIR__.'/../lang' => $this->app->langPath('vendor/scribe'),
|
||||
], 'scribe-translations');
|
||||
$this->configureTranslations();
|
||||
|
||||
// Bind the route matcher implementation
|
||||
$this->app->bind(RouteMatcherInterface::class, config('scribe.routeMatcher', RouteMatcher::class));
|
||||
@@ -52,6 +50,22 @@ class ScribeServiceProvider extends ServiceProvider
|
||||
}
|
||||
}
|
||||
|
||||
protected function configureTranslations(): void
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__.'/../lang/' => $this->app->langPath(),
|
||||
], 'scribe-translations');
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->loadTranslationsFrom($this->app->langPath('scribe.php'), 'scribe');
|
||||
$this->loadTranslationsFrom(realpath(__DIR__.'/../lang'), 'scribe');
|
||||
|
||||
$this->app->extend('translation.loader', function ($defaultFileLoader) {
|
||||
return new CustomTranslationsLoader($defaultFileLoader);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerViews(): void
|
||||
{
|
||||
// Register custom Markdown Blade compiler so we can automatically have MD views converted to HTML
|
||||
|
||||
@@ -363,12 +363,8 @@ class Utils
|
||||
{
|
||||
$translation = trans($key, $replace);
|
||||
|
||||
if ($translation === $key) {
|
||||
$translation = trans($key, $replace, config('app.fallback_locale'));
|
||||
}
|
||||
|
||||
if ($translation === $key) {
|
||||
return trans($key, $replace, 'en');
|
||||
if ($translation === $key || $translation === null) {
|
||||
$translation = trans($key, $replace, 'en');
|
||||
}
|
||||
|
||||
return $translation;
|
||||
|
||||
59
src/Writing/CustomTranslationsLoader.php
Normal file
59
src/Writing/CustomTranslationsLoader.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Knuckles\Scribe\Writing;
|
||||
|
||||
use Illuminate\Translation\FileLoader;
|
||||
use Knuckles\Scribe\Tools\Globals;
|
||||
|
||||
class CustomTranslationsLoader extends FileLoader
|
||||
{
|
||||
protected FileLoader $defaultLoader;
|
||||
protected mixed $path;
|
||||
|
||||
protected ?array $scribeTranslationsCache = null;
|
||||
protected ?array $userTranslationsCache = null;
|
||||
|
||||
public function __construct(FileLoader $loader)
|
||||
{
|
||||
$this->defaultLoader = $loader;
|
||||
$this->files = app('files');
|
||||
$this->path = app('path.lang');
|
||||
}
|
||||
|
||||
public function load($locale, $group, $namespace = null)
|
||||
{
|
||||
// Laravel expects translation strings to be broken up into groups (files):
|
||||
// `lang/scribe/en/auth.php`, `lang/scribe/en/links.php`
|
||||
// We want to trick it into accepting a simple `lang/scribe.php`.
|
||||
|
||||
if ($namespace == 'scribe') {
|
||||
if (isset($this->scribeTranslationsCache)) {
|
||||
$lines = $this->scribeTranslationsCache[$group] ?? [];
|
||||
} elseif ($this->files->exists($full = "{$this->hints[$namespace]}/scribe.php")) {
|
||||
$this->scribeTranslationsCache = $this->files->getRequire($full);
|
||||
$lines = $this->scribeTranslationsCache[$group] ?? [];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->loadScribeNamespaceOverrides($lines, $locale, $group, $namespace);
|
||||
}
|
||||
|
||||
return $this->defaultLoader->load($locale, $group, $namespace);
|
||||
}
|
||||
|
||||
protected function loadScribeNamespaceOverrides(array $lines, $locale, $group, $namespace)
|
||||
{
|
||||
$userTranslationsFile = "{$this->path}/scribe.php";
|
||||
|
||||
if ($this->files->exists($userTranslationsFile)) {
|
||||
if (!isset($this->userTranslationsCache)) {
|
||||
$this->userTranslationsCache = $this->files->getRequire($userTranslationsFile);
|
||||
}
|
||||
$userTranslations = $this->userTranslationsCache[$group] ?? [];
|
||||
return array_replace_recursive($lines, $userTranslations);
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user