new: add config hub
This commit is contained in:
parent
cb150c9280
commit
12e3b0c2d4
19
go.mod
19
go.mod
@ -3,23 +3,24 @@ module git.matterlinux.xyz/Matter/website
|
||||
go 1.21.4
|
||||
|
||||
require (
|
||||
github.com/gofiber/fiber/v2 v2.51.0
|
||||
github.com/gofiber/template/html/v2 v2.0.5
|
||||
github.com/gofiber/fiber/v2 v2.52.4
|
||||
github.com/gofiber/template/html/v2 v2.1.1
|
||||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/gofiber/template v1.8.2 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126 // indirect
|
||||
github.com/gofiber/template v1.8.3 // indirect
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/fasthttp v1.52.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
)
|
||||
|
20
go.sum
20
go.sum
@ -1,17 +1,31 @@
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126 h1:uru++pUKoS/yYU3Ohq9VItZdK/cT7FFJH/UUjOlxc+s=
|
||||
github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126/go.mod h1:zqqfbfnDeSdRs1WihmMjSbhb2Ptw8Jbus831xoqiIec=
|
||||
github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ=
|
||||
github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U=
|
||||
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
||||
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||
github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk=
|
||||
github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
||||
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template/html/v2 v2.0.5 h1:BKLJ6Qr940NjntbGmpO3zVa4nFNGDCi/IfUiDB9OC20=
|
||||
github.com/gofiber/template/html/v2 v2.0.5/go.mod h1:RCF14eLeQDCSUPp0IGc2wbSSDv6yt+V54XB/+Unz+LM=
|
||||
github.com/gofiber/template/html/v2 v2.1.1 h1:QEy3O3EBkvwDthy5bXVGUseOyO6ldJoiDxlF4+MJiV8=
|
||||
github.com/gofiber/template/html/v2 v2.1.1/go.mod h1:2G0GHHOUx70C1LDncoBpe4T6maQbNa4x1CVNFW0wju0=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@ -22,15 +36,21 @@ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
|
||||
github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
|
15
lib/util.go
15
lib/util.go
@ -1,12 +1,27 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// python3 -c "import string; print(string.ascii_letters+string.digits+\" /,_-?!'\\\"\")"
|
||||
var valid string = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 /,_-?!'"`
|
||||
|
||||
func IsStringValid(s string) bool{
|
||||
for _, c := range s {
|
||||
if !strings.Contains(valid, string(c)){
|
||||
fmt.Printf("%c\n", c)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func RenderError(c *fiber.Ctx, code int) error{
|
||||
var msg string = "Server Error"
|
||||
c.Status(code)
|
||||
|
3
main.go
3
main.go
@ -49,6 +49,9 @@ func main(){
|
||||
app.Get("/wiki", routes.WikiMainRoute)
|
||||
app.Get("/wiki/:id", routes.WikiRoute)
|
||||
|
||||
app.Get("/hub", routes.ConfigsRoute)
|
||||
app.Get("/hub/:id", routes.ConfigRoute)
|
||||
|
||||
app.Get("*", func(c *fiber.Ctx) error {
|
||||
return lib.RenderError(c, 404)
|
||||
})
|
||||
|
103
public/configs.css
Normal file
103
public/configs.css
Normal file
@ -0,0 +1,103 @@
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.config {
|
||||
padding: 26px;
|
||||
background: var(--dark-second);
|
||||
border: solid 1px var(--bright-second);
|
||||
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.config img {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.details pre{
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-family: JetBrainsMono;
|
||||
word-wrap: normal;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
line-height: 1.45;
|
||||
color: var(--bright-main);
|
||||
background-color: var(--dark-third);
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.details p {
|
||||
color: var(--bright-second);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.details table {
|
||||
border-collapse: collapse;
|
||||
margin: 10px 0 15px 0;
|
||||
width: 100%;
|
||||
border: solid 1px var(--bright-third);
|
||||
}
|
||||
|
||||
.details table td, .details table th{
|
||||
background: var(--dark-main);
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
border: solid 1px var(--bright-third);
|
||||
}
|
||||
|
||||
.details table th {
|
||||
color: var(--bright-main);
|
||||
font-weight: 900;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.details table td a {
|
||||
color: var(--bright-second);
|
||||
}
|
||||
|
||||
.details table td a:hover {
|
||||
color: var(--bright-main);
|
||||
}
|
||||
|
||||
.details table td {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.details h1 {
|
||||
margin-bottom: 2px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.details table {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.config {
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.config img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
126
routes/configs.go
Normal file
126
routes/configs.go
Normal file
@ -0,0 +1,126 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"git.matterlinux.xyz/Matter/website/lib"
|
||||
"github.com/bigkevmcd/go-configparser"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Redirect string `json:"redirect"`
|
||||
Image string `json:"image"`
|
||||
Url string `json:"url"`
|
||||
|
||||
Name string
|
||||
Desc string
|
||||
Author string
|
||||
Keywords string
|
||||
}
|
||||
|
||||
func LoadConfig(c *Config) (error) {
|
||||
agent := fiber.Get(c.Url)
|
||||
code, body, errs := agent.Bytes()
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("request to %s failed", c.Url)
|
||||
}
|
||||
|
||||
if code != 200 {
|
||||
return fmt.Errorf("bad response from %s", c.Url)
|
||||
}
|
||||
|
||||
parser := configparser.New()
|
||||
err := parser.ParseReader(bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse %s: %s", c.Url, err.Error())
|
||||
}
|
||||
|
||||
name, err := parser.Get("details", "name")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed get details/name: %s", c.Url)
|
||||
}
|
||||
|
||||
keywords, err := parser.Get("details", "keywords")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed get details/keywords: %s", c.Url)
|
||||
}
|
||||
|
||||
author, err := parser.Get("details", "author")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed get details/keywords: %s", c.Url)
|
||||
}
|
||||
|
||||
desc, err := parser.Get("details", "desc")
|
||||
|
||||
c.Name = name
|
||||
c.Desc = desc
|
||||
c.Author = author
|
||||
c.Keywords = strings.ReplaceAll(keywords, ",", ", ")
|
||||
|
||||
if(!lib.IsStringValid(c.Name) ||
|
||||
!lib.IsStringValid(c.Desc) ||
|
||||
!lib.IsStringValid(c.Author) ||
|
||||
!lib.IsStringValid(c.Keywords)){
|
||||
return fmt.Errorf("keywords or name contain illegal chars: %s", c.Url)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetConfigs() ([]Config, error) {
|
||||
var data map[string][]Config
|
||||
|
||||
configs_path := path.Join(lib.CONTENT_PATH, "configs.json")
|
||||
raw, err := os.ReadFile(configs_path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(raw, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := data["list"]; !ok {
|
||||
return nil, fmt.Errorf("json data does not contain the list key")
|
||||
}
|
||||
|
||||
for i := range data["list"] {
|
||||
err = LoadConfig(&data["list"][i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return data["list"], nil
|
||||
}
|
||||
|
||||
func ConfigsRoute(c *fiber.Ctx) error{
|
||||
con, err := lib.GetContent("", "configs")
|
||||
if err != nil {
|
||||
log.Printf("GetContent failed: %s", err.Error())
|
||||
return lib.RenderError(c, 500)
|
||||
}
|
||||
|
||||
configs, err := GetConfigs()
|
||||
if err != nil {
|
||||
log.Printf("GetConfigs failed: %s", err.Error())
|
||||
return lib.RenderError(c, 500)
|
||||
}
|
||||
|
||||
return c.Render("configs", fiber.Map{
|
||||
"content": con,
|
||||
"list": configs,
|
||||
})
|
||||
}
|
||||
|
||||
func ConfigRoute(c *fiber.Ctx) error{
|
||||
return c.Redirect("/configs")
|
||||
}
|
@ -15,6 +15,6 @@ func DownloadRoute(c *fiber.Ctx) error{
|
||||
}
|
||||
|
||||
return c.Render("download", fiber.Map{
|
||||
"readme": con,
|
||||
"content": con,
|
||||
})
|
||||
}
|
||||
|
55
templates/configs.html
Normal file
55
templates/configs.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>MatterLinux | Configs</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1200">
|
||||
<link href="/global.css" rel="stylesheet">
|
||||
<link href="/configs.css" rel="stylesheet">
|
||||
<link href="/md.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
{{template "parts/bar" .}}
|
||||
<main>
|
||||
<div class="md">
|
||||
<h1>Config Hub</h1>
|
||||
{{.content.HTML}}
|
||||
</div>
|
||||
<div class="list">
|
||||
{{range .list}}
|
||||
<div class="config">
|
||||
<img src="{{.Image}}">
|
||||
<div class="details">
|
||||
<h1>{{.Name}}</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
<td><a href="{{.Redirect}}">{{.Name}}</a></td>
|
||||
</tr>
|
||||
{{ if .Desc }}
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{.Desc}}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
<tr>
|
||||
<th>Author</th>
|
||||
<td>{{.Author}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Keywords</th>
|
||||
<td>{{.Keywords}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Run the following to install this
|
||||
confiugraiton:
|
||||
</p>
|
||||
<pre>$ mc-pull {{.Name}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -17,27 +17,27 @@
|
||||
<div class="list">
|
||||
<div class="entry">
|
||||
<h1>Version</h1>
|
||||
<h1>{{.readme.ID}}</h1>
|
||||
<h1>{{.content.ID}}</h1>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h1>Release Archive</h1>
|
||||
<div class="downloads">
|
||||
<a href="https://rel.matterlinux.xyz/{{.readme.Title}}/matterlinux_{{.readme.ID}}.tar.gz">Download</a>
|
||||
<a href="https://rel.matterlinux.xyz/{{.contentTitle}}/matterlinux_{{.content.ID}}.tar.gz">Download</a>
|
||||
<p>|</p>
|
||||
<a href="https://rel.matterlinux.xyz/{{.readme.Title}}/matterlinux_{{.readme.ID}}.tar.gz.sig">Signature</a>
|
||||
<a href="https://rel.matterlinux.xyz/{{.contentTitle}}/matterlinux_{{.content.ID}}.tar.gz.sig">Signature</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<h1>Release ISO</h1>
|
||||
<div class="downloads">
|
||||
<a href="https://rel.matterlinux.xyz/{{.readme.Title}}/matterlinux_{{.readme.ID}}.iso">Download</a>
|
||||
<a href="https://rel.matterlinux.xyz/{{.contentTitle}}/matterlinux_{{.content.ID}}.iso">Download</a>
|
||||
<p>|</p>
|
||||
<a href="https://rel.matterlinux.xyz/{{.readme.Title}}/matterlinux_{{.readme.ID}}.iso.sig">Signature</a>
|
||||
<a href="https://rel.matterlinux.xyz/{{.contentTitle}}/matterlinux_{{.content.ID}}.iso.sig">Signature</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="readme md">
|
||||
{{.readme.HTML}}
|
||||
<div class="content md">
|
||||
{{.content.HTML}}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
@ -4,7 +4,8 @@
|
||||
<title>MatterLinux | Error</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1200">
|
||||
<link href="/style.css" rel="stylesheet">
|
||||
<link href="/global.css" rel="stylesheet">
|
||||
<link href="/error.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="error">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<a href="/wiki">Wiki</a>
|
||||
<a href="https://git.matterlinux.xyz/Matter">Source</a>
|
||||
<a href="https://tracker.matterlinux.xyz">Packages</a>
|
||||
<a href="/hub">Configs</a>
|
||||
<a href="https://security.matterlinux.xyz">Security</a>
|
||||
<a href="/download">Download</a>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user