Compare commits
No commits in common. "bf228643dc026f23fc7375c3c3c31760ab990753" and "147ce945c373dafec91ba1671e4d9ae6997bd228" have entirely different histories.
bf228643dc
...
147ce945c3
82
README.md
82
README.md
@ -1,71 +1,70 @@
|
|||||||
# TCP-WIKI
|
H0wdy!!!
|
||||||
|
|
||||||
Feel free to commit, leave suggestions/ideas, issues, or really anything <3
|
feel free to commit, leave suggestions/ideas, issues, or really anything <3
|
||||||
|
|
||||||
# What is TCP-WIKI ?
|
# What is TCP.WIKI ?
|
||||||
<center><img src="https://tcp.ac/i/TIZzK" alt="example screenshot" width="100" height="400"></center>
|
|
||||||
|
|
||||||
TCP.WIKI is a secure and verifiable wiki platform designed for projects, code, courses, documents, articles, blogs, tutorials, and more.
|
https://tcp.ac/i/IFAZE
|
||||||
|
|
||||||
### Project Goals
|
|
||||||
|
|
||||||
The aim is to provide a secure, minimal, and easily verifiable wiki environment that supports a wide range of content types, from technical documentation, to educational materials, to blogs, and more.
|
## Project Goals
|
||||||
|
secure and verifiable wiki for projects, code, courses, documents, articles, tutorials, and more
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
**For a normal user you can follow this process:**
|
||||||
|
|
||||||
First clone this repository:
|
First clone the repo:
|
||||||
```bash
|
```bash
|
||||||
git clone https://git.tcp.direct/S4D/tcp-wiki.git
|
git clone https://git.tcp.direct/S4D/tcp-wiki.git
|
||||||
```
|
```
|
||||||
Then you have to cd into the repo's folder and run/compile:
|
Then you have to cd into the repo's folder and run/compile:
|
||||||
```bash
|
```bash
|
||||||
cd tcp-wiki
|
cd tcp-wiki/src
|
||||||
go run ./src
|
go run .
|
||||||
```
|
```
|
||||||
Then you goto your browser and visit: http://127.0.0.1:8080/
|
Then you goto your browser and visit: http://127.0.0.1:8080/
|
||||||
|
|
||||||
## Want to use with your own data?
|
**For a develeper setup you can follow this process:**
|
||||||
|
|
||||||
All you have to do is modify the following lines in the `config.toml` file:
|
First clone the repo:
|
||||||
|
```bash
|
||||||
```toml
|
git clone ssh://git@git.tcp.direct:2222/S4D/tcp-wiki.git
|
||||||
[Git]
|
|
||||||
UseGit = true # Set to false to use LocalPath
|
|
||||||
RepoURL = "https://git.tcp.direct/S4D/tcp-wiki.git" # Your Repo Here
|
|
||||||
Branch = "main" # Your Repo Branch Here
|
|
||||||
LocalPath = "data" # Directory to clone the git repo too
|
|
||||||
```
|
```
|
||||||
|
Then cd and run dev.sh
|
||||||
|
```bash
|
||||||
|
cd tcp-wiki
|
||||||
|
bash dev.sh
|
||||||
|
```
|
||||||
|
Then you just have to execute this to run the server:
|
||||||
|
```go
|
||||||
|
cd src && go run .
|
||||||
|
```
|
||||||
|
Then you goto your browser and visit: http://127.0.0.1:8080/
|
||||||
|
|
||||||
Change the `RepoURL` line `https://git.tcp.direct/S4D/tcp-wiki.git` to your repo link,
|
This method just adds in some handy symlinks for development purposes
|
||||||
|
|
||||||
|
## Want to use with your own repo?
|
||||||
|
|
||||||
|
All you have to do is modify the following lines in the src/main.go file:
|
||||||
|
```go
|
||||||
|
const repoURL = "https://git.tcp.direct/S4D/tcp-wiki.git"
|
||||||
|
```
|
||||||
|
Change `https://git.tcp.direct/S4D/tcp-wiki.git` to your repo link, and:
|
||||||
|
```go
|
||||||
|
const repoBRANCH = "main"
|
||||||
|
```
|
||||||
change `main` to your specific repo's branch and you should be good to go!
|
change `main` to your specific repo's branch and you should be good to go!
|
||||||
|
|
||||||
#### Want to use a local directory other then git repo?
|
|
||||||
|
|
||||||
To do this you just need to set `UseGit` to `false` and set your directory in config.toml
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[Git]
|
|
||||||
UseGit = false # Set this to false
|
|
||||||
RepoURL = "" # Ignored
|
|
||||||
Branch = "" # Ignored
|
|
||||||
LocalPath = "/home/crazy/blog" # The directory of your project
|
|
||||||
```
|
|
||||||
make sure to also set `LocalPath` to the directory of your project
|
|
||||||
|
|
||||||
> ### Want to use your own theme/layout?
|
|
||||||
>
|
|
||||||
> Have a look at the `assets/` directory for the templates
|
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [x] config file
|
- [ ] config files
|
||||||
- [ ] Webhook support for auto pull on push/update of the git repo
|
- [ ] Webhook support for auto pull on push/update of the git repo
|
||||||
- [x] Git Branch support
|
- [x] Git Branch support
|
||||||
- [ ] add a star/upvote/like feature for pages
|
- [ ] add a star/upvote/like feature for pages
|
||||||
- [x] edit/version tracker
|
- [x] edit/version tracker
|
||||||
- [x] Author
|
- [x] Author
|
||||||
- [x] last edited
|
- [x] last edited
|
||||||
- [x] last editor/commit - maybe working
|
- [ ] last editor/commit [?] maybe working
|
||||||
- [ ] PGP Signed & Verification
|
- [ ] PGP Signed & Verification
|
||||||
- [ ] pgp signed intergration
|
- [ ] pgp signed intergration
|
||||||
- [x] comments using bitcask - generated in comments.db/
|
- [x] comments using bitcask - generated in comments.db/
|
||||||
@ -77,6 +76,7 @@ make sure to also set `LocalPath` to the directory of your project
|
|||||||
- [ ] set security controls per page
|
- [ ] set security controls per page
|
||||||
- [ ] auto refresh on post
|
- [ ] auto refresh on post
|
||||||
- [x] dynamically generated links for all avaiable pages
|
- [x] dynamically generated links for all avaiable pages
|
||||||
- [x] sitemap - kinda
|
- [ ] sitemap
|
||||||
- [x] working pages
|
- [ ] anti robot shit here
|
||||||
|
- [x] acual working pages!?
|
||||||
- [ ] image support
|
- [ ] image support
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
{{ if .UseGit }}
|
|
||||||
<div class="page-info">
|
<div class="page-info">
|
||||||
{{- if eq .Author .LastModifier -}}
|
{{- if eq .Author .LastModifier -}}
|
||||||
Authored: {{ .Author }} @ {{ .AuthoredDate.Format "2006/01/02" }}
|
Authored: {{ .Author }} @ {{ .AuthoredDate.Format "2006/01/02" }}
|
||||||
@ -32,7 +31,6 @@
|
|||||||
Authored: {{ .Author }} @ {{ .AuthoredDate.Format "2006/01/02" }} - Modified: {{ .LastModifier }} @ {{ .LastModifiedDate.Format "2006/01/02" }}
|
Authored: {{ .Author }} @ {{ .AuthoredDate.Format "2006/01/02" }} - Modified: {{ .LastModifier }} @ {{ .LastModifiedDate.Format "2006/01/02" }}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
|
||||||
<div class="comments">
|
<div class="comments">
|
||||||
<h2>Comments</h2>
|
<h2>Comments</h2>
|
||||||
{{ range .Comments }}
|
{{ range .Comments }}
|
||||||
|
12
config.toml
12
config.toml
@ -1,12 +0,0 @@
|
|||||||
[Server]
|
|
||||||
Port = ":8080"
|
|
||||||
|
|
||||||
[Git]
|
|
||||||
UseGit = true
|
|
||||||
RepoURL = "https://git.tcp.direct/S4D/tcp-wiki.git"
|
|
||||||
Branch = "main"
|
|
||||||
LocalPath = "data"
|
|
||||||
|
|
||||||
[Database]
|
|
||||||
Path = "comments.db"
|
|
||||||
|
|
22
dev.sh
Normal file
22
dev.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#/bin/bash
|
||||||
|
# this sets up super annoying shit like hard symlinks and whatever else
|
||||||
|
# but for now we can manage by editing via hardlinks.
|
||||||
|
# This sets up your local readme as the main page and the files in assets as public
|
||||||
|
|
||||||
|
# Clone the repository
|
||||||
|
echo "Press Control+C when prompted"
|
||||||
|
go run ./src
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Set up hard links
|
||||||
|
# !!! for main branch only !!!
|
||||||
|
rm data/assets/*
|
||||||
|
ln assets/_layout.html data/assets/_layout.html
|
||||||
|
ln assets/main.css data/assets/main.css
|
||||||
|
rm data/README.md
|
||||||
|
ln README.md data/README.md
|
||||||
|
|
||||||
|
echo "Developer setup ready!"
|
||||||
|
echo "Go ahead and run go run src/"
|
||||||
|
echo "And Go to: http://127.0.0.1:8080"
|
1
go.mod
1
go.mod
@ -3,7 +3,6 @@ module git.tcp.direct/S4D/tcp-wiki
|
|||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
|
||||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20230331115716-d34776aa93ec // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.4 // indirect
|
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -12,8 +12,6 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
|
|||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||||
|
66
src/main.go
66
src/main.go
@ -14,46 +14,21 @@ import (
|
|||||||
|
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/prologic/bitcask"
|
"github.com/prologic/bitcask"
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
const repoURL = "https://git.tcp.direct/S4D/tcp-wiki.git"
|
||||||
Server struct {
|
const repoBRANCH = "main"
|
||||||
Port string
|
const localPath = "data"
|
||||||
}
|
|
||||||
Git struct {
|
|
||||||
UseGit bool
|
|
||||||
RepoURL string
|
|
||||||
Branch string
|
|
||||||
LocalPath string
|
|
||||||
}
|
|
||||||
Database struct {
|
|
||||||
Path string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var commentsDB *bitcask.Bitcask
|
var commentsDB *bitcask.Bitcask
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var config Config
|
err := cloneRepository(repoURL, localPath)
|
||||||
if _, err := toml.DecodeFile("config.toml", &config); err != nil {
|
|
||||||
log.Fatalf("Failed to load config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Git.UseGit {
|
|
||||||
err := cloneRepository(config.Git.RepoURL, config.Git.LocalPath)
|
|
||||||
if err != nil && err != git.ErrRepositoryAlreadyExists {
|
if err != nil && err != git.ErrRepositoryAlreadyExists {
|
||||||
log.Fatalf("Failed to clone repository: %v", err)
|
log.Fatalf("Failed to clone repository: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if _, err := os.Stat(config.Git.LocalPath); os.IsNotExist(err) {
|
|
||||||
os.MkdirAll(config.Git.LocalPath, os.ModePerm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
commentsDB, err = bitcask.Open("comments.db")
|
||||||
|
|
||||||
commentsDB, err = bitcask.Open(config.Database.Path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to open comments database: %v", err)
|
log.Fatalf("Failed to open comments database: %v", err)
|
||||||
}
|
}
|
||||||
@ -61,14 +36,10 @@ func main() {
|
|||||||
|
|
||||||
fs := http.FileServer(http.Dir("./assets"))
|
fs := http.FileServer(http.Dir("./assets"))
|
||||||
http.Handle("/assets/", http.StripPrefix("/assets/", fs))
|
http.Handle("/assets/", http.StripPrefix("/assets/", fs))
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", handler)
|
||||||
handler(&config, w, r)
|
http.HandleFunc("/submit_comment", submitCommentHandler)
|
||||||
})
|
|
||||||
http.HandleFunc("/submit_comment", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
submitCommentHandler(w, r)
|
|
||||||
})
|
|
||||||
|
|
||||||
srv := &http.Server{Addr: config.Server.Port}
|
srv := &http.Server{Addr: ":8080"}
|
||||||
go func() {
|
go func() {
|
||||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
log.Fatalf("ListenAndServe() failed: %v", err)
|
log.Fatalf("ListenAndServe() failed: %v", err)
|
||||||
@ -78,10 +49,12 @@ func main() {
|
|||||||
fmt.Println("Server running at http://127.0.0.1:8080")
|
fmt.Println("Server running at http://127.0.0.1:8080")
|
||||||
fmt.Println("Press Ctrl-C to stop the server")
|
fmt.Println("Press Ctrl-C to stop the server")
|
||||||
|
|
||||||
|
// Wait for interrupt signal to stop the server
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
<-c
|
<-c
|
||||||
|
|
||||||
|
// Shutdown the server gracefully
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if err := srv.Shutdown(ctx); err != nil {
|
if err := srv.Shutdown(ctx); err != nil {
|
||||||
@ -90,21 +63,17 @@ func main() {
|
|||||||
fmt.Println("Server stopped")
|
fmt.Println("Server stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
func handler(config *Config, w http.ResponseWriter, r *http.Request) {
|
func handler(w http.ResponseWriter, r *http.Request) {
|
||||||
// For debugging
|
// For debugging
|
||||||
log.Printf("Local Path: %q", config.Git.LocalPath)
|
log.Printf("LOCAL PATH: %q", localPath)
|
||||||
|
|
||||||
if r.URL.Path == "./assets/favicon.ico" {
|
if r.URL.Path == "./assets/favicon.ico" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Git.UseGit {
|
err := pullRepository(localPath, repoBRANCH)
|
||||||
err := pullRepository(config.Git.LocalPath, config.Git.Branch)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to pull repository: %v", err)
|
log.Printf("Failed to pull repository: %v", err)
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filePath := strings.TrimPrefix(r.URL.Path, "/")
|
filePath := strings.TrimPrefix(r.URL.Path, "/")
|
||||||
@ -117,34 +86,33 @@ func handler(config *Config, w http.ResponseWriter, r *http.Request) {
|
|||||||
csp := "default-src 'self'; img-src 'self'; script-src 'self'; style-src 'self';"
|
csp := "default-src 'self'; img-src 'self'; script-src 'self'; style-src 'self';"
|
||||||
w.Header().Set("Content-Security-Policy", csp)
|
w.Header().Set("Content-Security-Policy", csp)
|
||||||
|
|
||||||
markdownFiles, err := listMarkdownFiles(config.Git.LocalPath)
|
markdownFiles, err := listMarkdownFiles(localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error listing markdown files: %v", err)
|
log.Printf("Error listing markdown files: %v", err)
|
||||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = renderPage(w, r, config, filePath, commentsDB, markdownFiles)
|
err = renderPage(w, r, localPath, filePath, commentsDB, markdownFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to render page: %v", err)
|
log.Printf("Failed to render page: %v", err)
|
||||||
http.Error(w, "File not found", http.StatusNotFound)
|
http.Error(w, "File not found", http.StatusNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func listMarkdownFiles(localPath string) ([]string, error) {
|
func listMarkdownFiles(localPath string) ([]string, error) {
|
||||||
var files []string
|
var files []string
|
||||||
|
|
||||||
err := filepath.Walk(localPath, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(localPath, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !info.IsDir() && strings.HasSuffix(path, ".md") {
|
if !info.IsDir() && strings.HasSuffix(path, ".md") {
|
||||||
relPath, err := filepath.Rel(localPath, path)
|
relPath, err := filepath.Rel(localPath, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// Ensure the path uses web-friendly slashes
|
||||||
relPath = strings.Replace(relPath, string(os.PathSeparator), "/", -1)
|
relPath = strings.Replace(relPath, string(os.PathSeparator), "/", -1)
|
||||||
files = append(files, relPath)
|
files = append(files, relPath)
|
||||||
}
|
}
|
||||||
|
@ -21,34 +21,22 @@ type Page struct {
|
|||||||
Comments []Comment
|
Comments []Comment
|
||||||
Path string
|
Path string
|
||||||
Author string
|
Author string
|
||||||
AuthoredDate *time.Time
|
AuthoredDate time.Time
|
||||||
LastModifier string
|
LastModifier string
|
||||||
LastModifiedDate *time.Time
|
LastModifiedDate time.Time
|
||||||
Pages []string
|
Pages []string
|
||||||
UseGit bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderPage(w http.ResponseWriter, r *http.Request, config *Config, filePath string, commentsDB *bitcask.Bitcask, pages []string) error {
|
func renderPage(w http.ResponseWriter, r *http.Request, localPath, filePath string, commentsDB *bitcask.Bitcask, pages []string) error {
|
||||||
var content []byte
|
content, err := readFileFromRepo(localPath, filePath)
|
||||||
var err error
|
|
||||||
|
|
||||||
if config.Git.UseGit {
|
|
||||||
content, err = readFileFromRepo(config.Git.LocalPath, filePath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fullPath := filepath.Join(config.Git.LocalPath, filePath)
|
|
||||||
content, err = ioutil.ReadFile(fullPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ext := filepath.Ext(filePath)
|
ext := filepath.Ext(filePath)
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".md":
|
case ".md":
|
||||||
renderMarkdown(w, r, content, commentsDB, filePath, pages, config)
|
renderMarkdown(w, r, content, commentsDB, localPath, filePath, pages) // Now correctly includes `pages`
|
||||||
case ".html", ".css":
|
case ".html", ".css":
|
||||||
renderStatic(w, content, ext)
|
renderStatic(w, content, ext)
|
||||||
default:
|
default:
|
||||||
@ -57,31 +45,23 @@ func renderPage(w http.ResponseWriter, r *http.Request, config *Config, filePath
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderMarkdown(w http.ResponseWriter, r *http.Request, content []byte, commentsDB *bitcask.Bitcask, filePath string, pages []string, config *Config) {
|
|
||||||
|
func renderMarkdown(w http.ResponseWriter, r *http.Request, content []byte, commentsDB *bitcask.Bitcask, localPath, filePath string, pages []string) {
|
||||||
|
|
||||||
md := goldmark.New(
|
md := goldmark.New(
|
||||||
goldmark.WithExtensions(
|
goldmark.WithExtensions(
|
||||||
extension.GFM,
|
extension.GFM, // GitHub Flavored Markdown
|
||||||
highlighting.NewHighlighting(
|
highlighting.NewHighlighting(
|
||||||
highlighting.WithStyle("monokai"),
|
highlighting.WithStyle("monokai"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
var author, lastModifier string
|
author, authoredDate, lastModifier, lastModifiedDate, err := getAuthorAndLastModification(localPath, filePath)
|
||||||
var authoredDate, lastModifiedDate *time.Time
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if config.Git.UseGit {
|
|
||||||
var ad, lmd time.Time
|
|
||||||
author, ad, lastModifier, lmd, err = getAuthorAndLastModification(config.Git.LocalPath, filePath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error fetching author and last modification date", http.StatusInternalServerError)
|
http.Error(w, "Error fetching author and last modification date", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
authoredDate = &ad
|
|
||||||
lastModifiedDate = &lmd
|
|
||||||
}
|
|
||||||
|
|
||||||
var mdBuf bytes.Buffer
|
var mdBuf bytes.Buffer
|
||||||
err = md.Convert(content, &mdBuf)
|
err = md.Convert(content, &mdBuf)
|
||||||
@ -113,9 +93,7 @@ func renderMarkdown(w http.ResponseWriter, r *http.Request, content []byte, comm
|
|||||||
LastModifier: lastModifier,
|
LastModifier: lastModifier,
|
||||||
LastModifiedDate: lastModifiedDate,
|
LastModifiedDate: lastModifiedDate,
|
||||||
Pages: pages,
|
Pages: pages,
|
||||||
UseGit: config.Git.UseGit,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := template.New("layout").Parse(string(layout))
|
t, err := template.New("layout").Parse(string(layout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Error parsing layout", http.StatusInternalServerError)
|
http.Error(w, "Error parsing layout", http.StatusInternalServerError)
|
||||||
@ -125,7 +103,7 @@ func renderMarkdown(w http.ResponseWriter, r *http.Request, content []byte, comm
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err = t.Execute(&buf, page)
|
err = t.Execute(&buf, page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error executing template: %v", err)
|
log.Printf("Error executing template: %v", err) // Add this line
|
||||||
http.Error(w, "Error rendering layout", http.StatusInternalServerError)
|
http.Error(w, "Error rendering layout", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user