| <!-- |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| --> |
| {{define "header"}} |
| <!DOCTYPE html> |
| <html lang="{{.lang}}"> |
| <head> |
| <meta charset="utf-8" /> |
| <title>{{.title}}</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> |
| <meta name="theme-color" /> |
| <meta name="description" content="{{.description}}" data-rh="true" /> |
| <meta name="generator" content="Answer {{.Version}} - https://github.com/apache/answer version {{.Revision}}"> |
| {{if .keywords }}<meta name="keywords" content="{{.keywords}}" data-rh="true" />{{end}} |
| {{if .noindex }}<meta name="robots" content="noindex">{{end}} |
| |
| <link rel="canonical" href="{{.siteinfo.Canonical}}" /> |
| <link rel="manifest" href="{{$.baseURL}}/manifest.json" /> |
| <link rel="search" type="application/opensearchdescription+xml" href="{{$.baseURL}}/opensearch.xml" title="{{.siteinfo.General.Name}}" /> |
| <link href="{{.cssPath}}" rel="stylesheet" /> |
| <link href="{{$.baseURL}}/custom.css" rel="stylesheet" /> |
| <link |
| rel="icon" |
| type="image/png" |
| href="{{if $.siteinfo.Branding.Favicon }}{{$.siteinfo.Branding.Favicon}}{{else}}{{$.baseURL}}/favicon.ico{{end}}" |
| data-rh="true" |
| /> |
| <link |
| rel="icon" |
| type="image/png" |
| sizes="192x192" |
| href="{{.siteinfo.Branding.SquareIcon}}" |
| data-rh="true" |
| /> |
| <link |
| rel="apple-touch-icon" |
| type="image/png" |
| href="{{.siteinfo.Branding.SquareIcon}}" |
| data-rh="true" |
| /> |
| {{range $path := .scriptPath}} |
| <script defer="defer" src="{{$path}}"></script> |
| {{end}} |
| {{if $.siteinfo.JsonLD }}{{ .siteinfo.JsonLD | templateHTML}}{{end}} |
| |
| <meta property="og:type" content="website" /> |
| <meta property="og:title" name="twitter:title" content="{{.title}}" /> |
| <meta property="og:site_name" content="{{.siteinfo.General.Name}}" /> |
| <meta property="og:url" content="{{.siteinfo.Canonical}}" /> |
| <meta property="og:description" content="{{.description}}" /> |
| <meta |
| property="og:image" |
| itemProp="image primaryImageOfPage" |
| content="{{if $.siteinfo.Branding.Favicon }}{{$.siteinfo.Branding.Favicon}}{{else}}{{$.baseURL}}/favicon.ico{{end}}" |
| /> |
| <meta name="twitter:card" content="summary" /> |
| <meta name="twitter:domain" content="{{.siteinfo.General.SiteUrl}}" /> |
| <meta name="twitter:description" content="{{.description}}" /> |
| <meta |
| name="twitter:image" |
| content="{{if $.siteinfo.Branding.Favicon }}{{$.siteinfo.Branding.Favicon}}{{else}}{{$.baseURL}}/favicon.ico{{end}}" |
| /> |
| <meta name="go-template"> |
| <!--customize_head--> |
| {{if .HeadCode }} {{.HeadCode | templateHTML}} {{end}} |
| <!--customize_head--> |
| </head> |
| |
| <body> |
| <!--customize_header--> |
| {{if .HeaderCode }} {{.HeaderCode | templateHTML}} {{end}} |
| <!--customize_header--> |
| <div id="root"> |
| |
| <div id="spin-mask"> |
| <noscript> |
| <style> |
| #spin-mask { |
| display: none !important; |
| } |
| |
| #protect-browser { |
| display: none; |
| } |
| </style> |
| </noscript> |
| <style> |
| @keyframes _doc-spin { |
| to { transform: rotate(360deg) } |
| } |
| #spin-mask { |
| position: fixed; |
| top: 0; |
| right: 0; |
| bottom: 0; |
| left: 0; |
| background-color: white; |
| z-index: 9999; |
| } |
| #spin-container { |
| position: absolute; |
| top: 50%; |
| left: 50%; |
| transform: translate(-50%, -50%); |
| } |
| #spin-container .spinner { |
| box-sizing: border-box; |
| display: inline-block; |
| width: 2rem; |
| height: 2rem; |
| vertical-align: -.125em; |
| border: .25rem solid currentColor; |
| border-right-color: transparent; |
| color: rgba(108, 117, 125, .75); |
| border-radius: 50%; |
| animation: 0.75s linear infinite _doc-spin; |
| } |
| |
| #protect-browser { |
| padding: 20px; |
| text-align: center; |
| } |
| </style> |
| <div id="spin-container"> |
| <div class="spinner"></div> |
| </div> |
| <div id="protect-browser"></div> |
| </div> |
| |
| <nav id="header" class="sticky-top theme-dark navbar navbar-expand-xl navbar-light"> |
| <div class="w-100 d-flex align-items-center px-3"> |
| <button |
| aria-controls="navBarContent" |
| type="button" |
| aria-label="Toggle navigation" |
| class="answer-navBar me-2 navbar-toggler collapsed" |
| > |
| <span class="navbar-toggler-icon"></span> |
| </button> |
| <div |
| class="d-flex justify-content-between align-items-center nav-grow flex-nowrap" |
| > |
| {{if .siteinfo.Branding.Logo}} |
| <a class="lh-1 me-0 me-sm-5 p-0 navbar-brand" href="{{$.baseURL}}/"> |
| <img class="logo me-0" src="{{.siteinfo.Branding.Logo}}" alt="{{.siteinfo.General.Name}}"> |
| </a> |
| {{else}} |
| <a class="lh-1 me-0 me-sm-3 navbar-brand" href="{{$.baseURL}}/"> |
| {{.siteinfo.General.Name}} |
| </a> |
| {{end}} |
| </div> |
| <div class="d-none d-xl-block flex-grow-1 me-auto"> |
| <div class="d-none d-xl-block ps-0 col-lg-8"> |
| <form action="/search" class="w-100 maxw-400"> |
| <input placeholder="Search" name="q" type="search" class="placeholder-search form-control" value=""> |
| </form> |
| </div> |
| <!-- <div class="xl-none mt-3 pb-1 nav-item"> |
| <a class="text-capitalize text-nowrap btn btn-light" href="/questions/add">{{translator $.language "ui.btns.add_question"}}</a> |
| </div> --> |
| <div class="d-none d-xl-flex justify-content-start justify-content-sm-end col-lg-4"> |
| <!-- <a role="button" tabindex="0" href="/users/login" class="me-2 link-light btn btn-link"> |
| {{translator $.language "ui.btns.login"}} |
| </a> |
| <a role="button" tabindex="0" href="/users/register" class="btn btn-light"> |
| {{translator $.language "ui.btns.signup"}} |
| </a> --> |
| </div> |
| </div> |
| </div> |
| </nav> |
| <div class="position-relative page-wrap d-flex flex-column flex-fill"> |
| <div class="d-flex"> |
| <div class="position-sticky px-3 border-end pt-4 d-none d-xl-block" id="pcSideNav"> |
| {{template "sidenav" . }} |
| </div> |
| <div class="flex-fill w-100 overflow-x-hidden"> |
| {{end}} |
| </div> |
| </div> |
| </div> |
| |
| </div> |
| </body> |
| <script> |
| /** |
| * @description: Prompt that the browser version is too low |
| */ |
| const defaultList = [ |
| { |
| name: 'Edge', |
| version: '100' |
| }, |
| { |
| name: 'Firefox', |
| version: '100' |
| }, |
| { |
| name: 'Chrome', |
| version: '90' |
| }, |
| { |
| name: 'Safari', |
| version: '15' |
| }, |
| { |
| name: 'IE', |
| } |
| ]; |
| function getBrowserTypeAndVersion(){ |
| var browser = { |
| name: '', |
| version: '' |
| }; |
| var ua = navigator.userAgent.toLowerCase(); |
| var s; |
| ((ua.indexOf("compatible") > -1 && ua.indexOf("MSIE") > -1) || (ua.indexOf('Trident') > -1 && ua.indexOf("rv:11.0") > -1)) ? browser = { name: 'IE', version: '' } : |
| (s = ua.match(/edge\/([\d\.]+)/)) ? browser = { name: 'Edge', version: s[1] } : |
| (s = ua.match(/firefox\/([\d\.]+)/)) ? browser = { name: 'Firefox', version: s[1] } : |
| (s = ua.match(/chrome\/([\d\.]+)/)) ? browser = { name: 'Chrome', version: s[1] } : |
| (s = ua.match(/version\/([\d\.]+).*safari/)) ? browser = { name: 'Safari', version: s[1] } : browser = { name: 'unknown', version: '' }; |
| // 根据关系进行判断 |
| return browser; |
| } |
| |
| function compareVersion(version1, version2) { |
| var v1 = version1.split('.'); |
| var v2 = version2.split('.'); |
| var len = Math.max(v1.length, v2.length); |
| while (v1.length < len) { |
| v1.push('0'); |
| } |
| while (v2.length < len) { |
| v2.push('0'); |
| } |
| for (var i = 0; i < len; i++) { |
| var num1 = parseInt(v1[i]); |
| var num2 = parseInt(v2[i]); |
| if (num1 >= num2) { |
| return 1; |
| } else if (num1 < num2) { |
| return -1; |
| } |
| } |
| return 0; |
| } |
| |
| const browserInfo = getBrowserTypeAndVersion(); |
| |
| if (browserInfo.name === 'IE') { |
| const div = document.getElementById('protect-browser'); |
| div.innerText = 'Sorry, this site does not support Internet Explorer. In order to avoid affecting the normal use of our features, please use a more modern browser such as Edge, Firefox, Chrome, or Safari.' |
| } else { |
| const notSupport = defaultList.some(item => { |
| if (item.name === browserInfo.name) { |
| return compareVersion(browserInfo.version, item.version) === -1; |
| } |
| return false; |
| }); |
| if (notSupport) { |
| const div = document.getElementById('protect-browser'); |
| div.innerText = 'The current browser version is too low, in order not to affect the normal use of the function, please upgrade the browser to the latest version.' |
| } |
| } |
| |
| </script> |
| |
| </html> |