mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
wip: 🔕 temporary commit
This commit is contained in:
parent
1682a3513f
commit
2a1fa5c108
@ -20,7 +20,7 @@ func TestNew(t *testing.T) {
|
||||
assert.NotEmpty(t, cfg.Formats.JSON)
|
||||
assert.NotEmpty(t, cfg.Formats.PlainText)
|
||||
assert.True(t, len(cfg.Codes) >= 19)
|
||||
assert.True(t, len(cfg.Templates) >= 2)
|
||||
assert.True(t, len(cfg.Templates) >= 1)
|
||||
assert.NotEmpty(t, cfg.TemplateName)
|
||||
assert.True(t, cfg.Templates.Has(cfg.TemplateName))
|
||||
assert.Equal(t, uint16(http.StatusNotFound), cfg.DefaultCodeToRender)
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
const contentTypeHeader = "Content-Type"
|
||||
|
||||
// New creates a new handler that returns an error page with the specified status code and format.
|
||||
func New(cfg *config.Config, log *logger.Logger) http.Handler { //nolint:funlen,gocognit
|
||||
func New(cfg *config.Config, log *logger.Logger) http.Handler { //nolint:funlen,gocognit,gocyclo
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var code uint16
|
||||
|
||||
@ -86,6 +86,7 @@ func New(cfg *config.Config, log *logger.Logger) http.Handler { //nolint:funlen,
|
||||
tplProps.Host = r.Header.Get("Host") // the value of the `Host` header
|
||||
}
|
||||
|
||||
// TODO: ADD SUPPORT FOR THE RANDOM TEMPLATE AND SO ON
|
||||
// try to find the code message and description in the config and if not - use the standard status text or fallback
|
||||
if desc, found := cfg.Codes.Find(code); found {
|
||||
tplProps.Message = desc.Message
|
||||
@ -140,7 +141,7 @@ func New(cfg *config.Config, log *logger.Logger) http.Handler { //nolint:funlen,
|
||||
}
|
||||
} else {
|
||||
write(w, log, `The requested content format is not supported.
|
||||
Please create an issue on the project's GitHub page to request support for it.
|
||||
Please create an issue on the project's GitHub page to request support for this format.
|
||||
|
||||
Supported formats: JSON, XML, HTML, Plain Text`)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"gh.tarampamp.am/error-pages/internal/appmeta"
|
||||
"gh.tarampamp.am/error-pages/l10n"
|
||||
)
|
||||
|
||||
var builtInFunctions = template.FuncMap{ //nolint:gochecknoglobals
|
||||
@ -99,6 +100,10 @@ var builtInFunctions = template.FuncMap{ //nolint:gochecknoglobals
|
||||
// retrieves the value of the environment variable named by the key:
|
||||
// `{{ env "SHELL" }}` // `/bin/bash`
|
||||
"env": os.Getenv,
|
||||
|
||||
// returns the content of the JS file with a script for automatic error page localization:
|
||||
// `{{ l10nScript }}` // `Object.defineProperty(window, ...`
|
||||
"l10nScript": l10n.L10n,
|
||||
}
|
||||
|
||||
func Render(content string, props Props) (string, error) {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"gh.tarampamp.am/error-pages/internal/appmeta"
|
||||
"gh.tarampamp.am/error-pages/internal/template"
|
||||
"gh.tarampamp.am/error-pages/l10n"
|
||||
)
|
||||
|
||||
func TestRender_BuiltInFunction(t *testing.T) {
|
||||
@ -29,10 +30,6 @@ func TestRender_BuiltInFunction(t *testing.T) {
|
||||
giveTemplate: `{{ now.Unix }}`,
|
||||
wantResult: strconv.Itoa(int(time.Now().Unix())),
|
||||
},
|
||||
"now (time)": {
|
||||
giveTemplate: `{{ now.Hour }}:{{ now.Minute }}:{{ now.Second }}`,
|
||||
wantResult: time.Now().Format("15:4:5"),
|
||||
},
|
||||
"hostname": {giveTemplate: `{{ hostname }}`, wantResult: hostname},
|
||||
"json (string)": {giveTemplate: `{{ json "test" }}`, wantResult: `"test"`},
|
||||
"json (int)": {giveTemplate: `{{ json 42 }}`, wantResult: `42`},
|
||||
@ -54,6 +51,7 @@ func TestRender_BuiltInFunction(t *testing.T) {
|
||||
"strFields": {giveTemplate: `{{ strFields "foo bar baz" }}`, wantResult: `[foo bar baz]`},
|
||||
"env (ok)": {giveTemplate: `{{ env "TEST_ENV_VAR" }}`, wantResult: "unit-test"},
|
||||
"env (not found)": {giveTemplate: `{{ env "NOT_FOUND_ENV_VAR" }}`, wantResult: ""},
|
||||
"l10nScript": {giveTemplate: `{{ l10nScript }}`, wantResult: l10n.L10n()},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
require.NoError(t, os.Setenv("TEST_ENV_VAR", "unit-test"))
|
||||
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
}
|
14
l10n/embed_test.go
Normal file
14
l10n/embed_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
package l10n_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gh.tarampamp.am/error-pages/l10n"
|
||||
)
|
||||
|
||||
func TestL10n(t *testing.T) {
|
||||
assert.NotEmpty(t, l10n.L10n())
|
||||
assert.Contains(t, l10n.L10n(), "data-l10n")
|
||||
}
|
9
l10n/enbed.go
Normal file
9
l10n/enbed.go
Normal file
@ -0,0 +1,9 @@
|
||||
package l10n
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed l10n.js
|
||||
var content string
|
||||
|
||||
// L10n returns the content of the JS file with a script for automatic error page localization.
|
||||
func L10n() string { return content }
|
1875
l10n/l10n.js
1875
l10n/l10n.js
File diff suppressed because it is too large
Load Diff
138
l10n/playground.html
Normal file
138
l10n/playground.html
Normal file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>L10n playground</title>
|
||||
<style>
|
||||
:root {
|
||||
--color-bg-primary: #fff;
|
||||
--color-text-primary: #0e0620;
|
||||
--color-ui-bg-primary: #0e0620;
|
||||
--color-ui-bg-inverted: #fff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-bg-primary: #212121;
|
||||
--color-text-primary: #fafafa;
|
||||
--color-ui-bg-primary: #fafafa;
|
||||
--color-ui-bg-inverted: #212121;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 1200px;
|
||||
min-width: 400px;
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
#lang-switch {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
flex-grow: 4;
|
||||
gap: 1em;
|
||||
padding: 2em 0;
|
||||
|
||||
button {
|
||||
background-color: var(--color-bg-primary);
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-text-primary);
|
||||
padding: 0.5em 1em;
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
border-radius: 1em 0 1em 0;
|
||||
transition: background-color 0.3s, color 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-ui-bg-primary);
|
||||
color: var(--color-ui-bg-inverted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#tokens-list {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 1em;
|
||||
padding: 0 1em;
|
||||
|
||||
li {
|
||||
padding: 0.5em 1em;
|
||||
font-size: 1.2em;
|
||||
|
||||
&::first-letter {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul id="lang-switch"></ul>
|
||||
<ul id="tokens-list"></ul>
|
||||
<script type="module">
|
||||
const $tokensList = document.getElementById('tokens-list');
|
||||
|
||||
[
|
||||
'Error', 'Good luck', 'UH OH', 'Request details', 'Double-check the URL', 'Alternatively, go back', 'Host',
|
||||
"Here's what might have happened", 'You may have mistyped the URL', 'The site was moved', 'It was never here',
|
||||
'Bad Request', 'The server did not understand the request', 'Unauthorized', 'Method Not Allowed', 'Bad Gateway',
|
||||
'The requested page needs a username and a password', 'Forbidden', 'Access is forbidden to the requested page',
|
||||
'Not Found', 'The server can not find the requested page', 'The method specified in the request is not allowed',
|
||||
'Proxy Authentication Required', 'You must authenticate with a proxy server before this request can be served',
|
||||
'Request Timeout', 'The request took longer than the server was prepared to wait', 'Conflict', "I'm a teapot",
|
||||
'The request could not be completed because of a conflict', 'Gone', 'The requested page is no longer available',
|
||||
'Length Required', 'The "Content-Length" is not defined. The server will not accept the request without it',
|
||||
'Precondition Failed', 'The pre condition given in the request evaluated to false by the server', 'Namespace',
|
||||
'Payload Too Large', 'The server will not accept the request, because the request entity is too large',
|
||||
'Requested Range Not Satisfiable', 'The requested byte range is not available and is out of bounds',
|
||||
'Attempt to brew coffee with a teapot is not supported', 'Too Many Requests', 'Gateway Timeout', 'Service port',
|
||||
'Too many requests in a given amount of time', 'Internal Server Error', 'The server met an unexpected condition',
|
||||
'The server received an invalid response from the upstream server', 'Service Unavailable', 'Service name',
|
||||
'The server is temporarily overloading or down', 'The gateway has timed out', 'HTTP Version Not Supported',
|
||||
'The server does not support the "http protocol" version', 'Original URI', 'Forwarded for', 'Ingress name',
|
||||
'Request ID', 'Timestamp', 'client-side error', 'server-side error', 'Your Client', 'Network', 'Web Server',
|
||||
'What happened?', 'What can i do?', 'Please try again in a few minutes', 'Working', 'Unknown',
|
||||
'Please try to change the request method, headers, payload, or URL', 'Please check your authorization data',
|
||||
'Please double-check the URL and try again',
|
||||
].forEach((token) => {
|
||||
const $li = document.createElement('li');
|
||||
|
||||
$li.textContent = token;
|
||||
$li.setAttribute('data-l10n', '');
|
||||
$li.title = token;
|
||||
|
||||
$tokensList.appendChild($li);
|
||||
});
|
||||
|
||||
const $langSwitch = document.getElementById('lang-switch');
|
||||
|
||||
['fr', 'ru', 'uk', 'pt', 'nl', 'de', 'es', 'zh', 'id', 'pl'].forEach((lang) => {
|
||||
// ^^^ add your newly added locale here
|
||||
const $li = document.createElement('li');
|
||||
const $btn = document.createElement('button');
|
||||
|
||||
$btn.textContent = lang;
|
||||
$btn.addEventListener('click', () => {
|
||||
window.l10n.setLocale(lang);
|
||||
window.l10n.localizeDocument();
|
||||
});
|
||||
|
||||
$li.appendChild($btn);
|
||||
$langSwitch.appendChild($li);
|
||||
});
|
||||
</script>
|
||||
<script src="l10n.js" defer async></script>
|
||||
</body>
|
||||
</html>
|
@ -1,15 +1,22 @@
|
||||
# 🔤 Localization
|
||||
|
||||
[](https://www.jsdelivr.com/package/gh/tarampampam/error-pages)
|
||||
This directory contains the file [l10n.js](l10n.js) for localizing error pages. Once the error page is loaded,
|
||||
this script runs and translates the page content to the user's locale.
|
||||
|
||||
This directory contains file [l10n.js](l10n.js) for the error pages localization. The working logic is very simple - pages load this script using [jsdelivr.com](https://www.jsdelivr.com/) as a CDN for [versioned content from the GitHub repository](https://www.jsdelivr.com/features#gh), and it translates tag content with the special HTML attribute `data-l10n`.
|
||||
> [!NOTE]
|
||||
> In version `2.*`, the working logic was simpler: error pages loaded this script using
|
||||
> [jsdelivr.com](https://www.jsdelivr.com/) as a CDN for
|
||||
> [versioned content from the GitHub repository](https://www.jsdelivr.com/features#gh), and it translated
|
||||
> tag content with the special HTML attribute `data-l10n`.
|
||||
|
||||
By default, pages markup contains strings in English (`en` locale). If you want to localize the error pages on the different locales, you should:
|
||||
By default, the error page markup contains strings in English (`en` locale). To localize the error pages to
|
||||
different locales, please follow these steps:
|
||||
|
||||
- Find your locale name on [this page](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (column `639-1`)
|
||||
- Make a fork of this repository
|
||||
- Edit file [l10n.js](l10n.js) in `data` section (append new localized strings) using locale name from the step 1
|
||||
- Make a PR with your changes
|
||||
1. Find your locale name on [this page](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (column `Set 1` or `ISO 639-1:2002`)
|
||||
2. Fork this repository
|
||||
3. Edit the file [l10n.js](l10n.js) in the `data` map (append new localized strings) using the locale name from step 1
|
||||
4. Please add your locale to the [playground.html](playground.html) file to test the localization
|
||||
5. Make a PR with your changes
|
||||
|
||||
## 👍 Translators
|
||||
|
||||
|
@ -10,9 +10,10 @@ import (
|
||||
//go:embed *.html
|
||||
var content embed.FS
|
||||
|
||||
func BuiltIn() map[string]string { // error check is covered by unit tests
|
||||
// BuiltIn returns a map of built-in templates. The key is the template name and the value is the template content.
|
||||
func BuiltIn() map[string]string {
|
||||
var (
|
||||
list, _ = fs.ReadDir(content, ".")
|
||||
list, _ = fs.ReadDir(content, ".") // error check is covered by unit tests
|
||||
result = make(map[string]string, len(list))
|
||||
)
|
||||
|
||||
|
118
templates/ghost.html
Normal file
118
templates/ghost.html
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<title>{{ code }}: {{ message }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="preconnect" href="https://fonts.bunny.net" crossorigin>
|
||||
<link rel="dns-prefetch" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css2?family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
html,body {background-color:#1a1a1a;color:#fff;font-family:'Open Sans',sans-serif;height:100vh;margin:0;font-size:0}
|
||||
.container {height:100vh;align-items:center;display:flex;justify-content:center;position:relative}
|
||||
.wrap {text-align:center}
|
||||
.ghost {animation:float 3s ease-out infinite}
|
||||
@keyframes float { 50% {transform:translate(0,20px)}}
|
||||
.shadowFrame {width:130px;margin: 10px auto 0 auto}
|
||||
.shadow {animation:shrink 3s ease-out infinite;transform-origin:center center}
|
||||
@keyframes shrink {0%{width:90%;margin:0 5%} 50% {width:60%;margin:0 18%} 100% {width:90%;margin:0 5%}}
|
||||
h3 {font-size:17px;text-transform: uppercase;margin:0.3em auto}
|
||||
.description {font-size:13px;color:#aaa}
|
||||
/* {{ if show_details }} */
|
||||
.details {color:#999;width:100%}
|
||||
.details table {width:100%}
|
||||
.details td {white-space:nowrap;font-size:11px}
|
||||
.details .name {text-align:right;padding-right:.6em;width:50%}
|
||||
.details .value {text-align:left;padding-left:.6em;font-family:'Lucida Console','Courier New',monospace}
|
||||
/* {{ end }} */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="wrap">
|
||||
<svg class="ghost" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="127.433px" height="132.743px" viewBox="0 0 127.433 132.743" xml:space="preserve">
|
||||
<path fill="#FFF6F4" d="M116.223,125.064c1.032-1.183,1.323-2.73,1.391-3.747V54.76c0,0-4.625-34.875-36.125-44.375 s-66,6.625-72.125,44l-0.781,63.219c0.062,4.197,1.105,6.177,1.808,7.006c1.94,1.811,5.408,3.465,10.099-0.6 c7.5-6.5,8.375-10,12.75-6.875s5.875,9.75,13.625,9.25s12.75-9,13.75-9.625s4.375-1.875,7,1.25s5.375,8.25,12.875,7.875 s12.625-8.375,12.625-8.375s2.25-3.875,7.25,0.375s7.625,9.75,14.375,8.125C114.739,126.01,115.412,125.902,116.223,125.064z"></path>
|
||||
<circle fill="#1a1a1a" cx="86.238" cy="57.885" r="6.667"></circle>
|
||||
<circle fill="#1a1a1a" cx="40.072" cy="57.885" r="6.667"></circle>
|
||||
<path fill="#1a1a1a" d="M71.916,62.782c0.05-1.108-0.809-2.046-1.917-2.095c-0.673-0.03-1.28,0.279-1.667,0.771 c-0.758,0.766-2.483,2.235-4.696,2.358c-1.696,0.094-3.438-0.625-5.191-2.137c-0.003-0.003-0.007-0.006-0.011-0.009l0.002,0.005 c-0.332-0.294-0.757-0.488-1.235-0.509c-1.108-0.049-2.046,0.809-2.095,1.917c-0.032,0.724,0.327,1.37,0.887,1.749 c-0.001,0-0.002-0.001-0.003-0.001c2.221,1.871,4.536,2.88,6.912,2.986c0.333,0.014,0.67,0.012,1.007-0.01 c3.163-0.191,5.572-1.942,6.888-3.166l0.452-0.453c0.021-0.019,0.04-0.041,0.06-0.061l0.034-0.034 c-0.007,0.007-0.015,0.014-0.021,0.02C71.666,63.771,71.892,63.307,71.916,62.782z"></path>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="18.614" cy="99.426" r="3.292"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="95.364" cy="28.676" r="3.291"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="24.739" cy="93.551" r="2.667"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="101.489" cy="33.051" r="2.666"></circle>
|
||||
<circle fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" cx="18.738" cy="87.717" r="2.833"></circle>
|
||||
<path fill="#FCEFED" stroke="#FEEBE6" stroke-miterlimit="10" d="M116.279,55.814c-0.021-0.286-2.323-28.744-30.221-41.012 c-7.806-3.433-15.777-5.173-23.691-5.173c-16.889,0-30.283,7.783-37.187,15.067c-9.229,9.736-13.84,26.712-14.191,30.259 l-0.748,62.332c0.149,2.133,1.389,6.167,5.019,6.167c1.891,0,4.074-1.083,6.672-3.311c4.96-4.251,7.424-6.295,9.226-6.295 c1.339,0,2.712,1.213,5.102,3.762c4.121,4.396,7.461,6.355,10.833,6.355c2.713,0,5.311-1.296,7.942-3.962 c3.104-3.145,5.701-5.239,8.285-5.239c2.116,0,4.441,1.421,7.317,4.473c2.638,2.8,5.674,4.219,9.022,4.219 c4.835,0,8.991-2.959,11.27-5.728l0.086-0.104c1.809-2.2,3.237-3.938,5.312-3.938c2.208,0,5.271,1.942,9.359,5.936 c0.54,0.743,3.552,4.674,6.86,4.674c1.37,0,2.559-0.65,3.531-1.932l0.203-0.268L116.279,55.814z M114.281,121.405 c-0.526,0.599-1.096,0.891-1.734,0.891c-2.053,0-4.51-2.82-5.283-3.907l-0.116-0.136c-4.638-4.541-7.975-6.566-10.82-6.566 c-3.021,0-4.884,2.267-6.857,4.667l-0.086,0.104c-1.896,2.307-5.582,4.999-9.725,4.999c-2.775,0-5.322-1.208-7.567-3.59 c-3.325-3.528-6.03-5.102-8.772-5.102c-3.278,0-6.251,2.332-9.708,5.835c-2.236,2.265-4.368,3.366-6.518,3.366 c-2.772,0-5.664-1.765-9.374-5.723c-2.488-2.654-4.29-4.395-6.561-4.395c-2.515,0-5.045,2.077-10.527,6.777 c-2.727,2.337-4.426,2.828-5.37,2.828c-2.662,0-3.017-4.225-3.021-4.225l0.745-62.163c0.332-3.321,4.767-19.625,13.647-28.995 c3.893-4.106,10.387-8.632,18.602-11.504c-0.458,0.503-0.744,1.165-0.744,1.898c0,1.565,1.269,2.833,2.833,2.833 c1.564,0,2.833-1.269,2.833-2.833c0-1.355-0.954-2.485-2.226-2.764c4.419-1.285,9.269-2.074,14.437-2.074 c7.636,0,15.336,1.684,22.887,5.004c26.766,11.771,29.011,39.047,29.027,39.251V121.405z"></path>
|
||||
</svg>
|
||||
<p class="shadowFrame">
|
||||
<svg class="shadow" xmlns="http://www.w3.org/2000/svg" x="61px" y="20px" width="122.436px" height="39.744px" viewBox="0 0 122.436 39.744" xml:space="preserve">
|
||||
<ellipse fill="#262626" cx="61.128" cy="19.872" rx="49.25" ry="8.916"></ellipse>
|
||||
</svg>
|
||||
</p>
|
||||
<h3><span data-l10n>Error</span> {{ code }}</h3>
|
||||
<p class="description" data-l10n>{{ description }}</p>
|
||||
{{ if show_details }}
|
||||
<div class="details">
|
||||
<table>
|
||||
{{- if host }}<tr>
|
||||
<td class="name" data-l10n>Host</td>
|
||||
<td class="value">{{ host }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if original_uri }}<tr>
|
||||
<td class="name" data-l10n>Original URI</td>
|
||||
<td class="value">{{ original_uri }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if forwarded_for }}<tr>
|
||||
<td class="name" data-l10n>Forwarded for</td>
|
||||
<td class="value">{{ forwarded_for }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if namespace }}<tr>
|
||||
<td class="name" data-l10n>Namespace</td>
|
||||
<td class="value">{{ namespace }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if ingress_name }}<tr>
|
||||
<td class="name" data-l10n>Ingress name</td>
|
||||
<td class="value">{{ ingress_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_name }}<tr>
|
||||
<td class="name" data-l10n>Service name</td>
|
||||
<td class="value">{{ service_name }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if service_port }}<tr>
|
||||
<td class="name" data-l10n>Service port</td>
|
||||
<td class="value">{{ service_port }}</td>
|
||||
</tr>{{ end -}}
|
||||
{{- if request_id }}<tr>
|
||||
<td class="name" data-l10n>Request ID</td>
|
||||
<td class="value">{{ request_id }}</td>
|
||||
</tr>{{ end -}}
|
||||
<tr>
|
||||
<td class="name" data-l10n>Timestamp</td>
|
||||
<td class="value">{{ now.Unix }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// {{ if l10n_enabled }}
|
||||
if (navigator.language.substring(0, 2).toLowerCase() !== 'en') {
|
||||
((s, p) => { // localize the page (details here - https://github.com/tarampampam/error-pages/tree/master/l10n)
|
||||
s.src = 'https://cdn.jsdelivr.net/gh/tarampampam/error-pages@2/l10n/l10n.min.js'; // '../l10n/l10n.js';
|
||||
s.async = s.defer = true;
|
||||
s.addEventListener('load', () => p.removeChild(s));
|
||||
p.appendChild(s);
|
||||
})(document.createElement('script'), document.body);
|
||||
}
|
||||
// {{ end }}
|
||||
</script>
|
||||
</body>
|
||||
<!--
|
||||
Error {{ code }}: {{ message }}
|
||||
Description: {{ description }}
|
||||
-->
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Template 1</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Template 2</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user