Parcourir la source

added nav_big partial

turos.robert il y a 1 semaine
Parent
commit
0c205ca2ee

+ 3 - 2
cmds/webservice/bin/mynotes_cfg.json

@@ -1,12 +1,13 @@
 {
   "srvhost": "0.0.0.0",
-  "srvport": "3000",
+  "srvport": "3005",
   "notes_directory": "notes_folder",
   "routes": {
     "/list_notes/": "LIST_NOTES",
     "/notes/": "VIEW_NOTE",
     "/edit/": "EDIT_NOTE",
     "/api/" : "API",
-    "/live_preview/" : "MKDOWN_CONVERT"
+    "/live_preview/" : "MKDOWN_CONVERT",
+    "/design_view/" : "DESIGN_VIEW"
   }
 }

+ 6 - 0
cmds/webservice/bin/notes_folder/Carti/Crima-Si-Pedeapsa/notita-2026-03-24-211514.15892.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "Carti/Crima-Si-Pedeapsa",
+  "Path": "notes_folder/Carti/Crima-Si-Pedeapsa/notita-2026-03-24-211514.15892.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/Crima-Si-Pedeapsa/notita-2026-03-24-210114.717444.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "Crima-Si-Pedeapsa",
+  "Path": "notes_folder/Crima-Si-Pedeapsa/notita-2026-03-24-210114.717444.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/Scoala/notita-2026-03-21-130225.401224.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "George Scoala",
+  "continut": "adfweyagfdyuwevbadwad",
+  "director": "Scoala",
+  "Path": "notes_folder/Scoala/notita-2026-03-21-130225.401224.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/Scoala/notita-2026-03-24-203703.707033.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "wdad",
+  "continut": "dwzda",
+  "director": "Scoala",
+  "Path": "notes_folder/Scoala/notita-2026-03-24-203703.707033.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/Scoala/notita-2026-03-24-204538.379749.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "Scoala",
+  "Path": "notes_folder/Scoala/notita-2026-03-24-204538.379749.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/notita-2026-03-24-210133.110762.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "notes_folder/Carti/Crima-Si-Pedeapsa",
+  "Path": "notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/notita-2026-03-24-210133.110762.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/test/test/notita-2026-03-24-221723.816195.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "notes_folder/Carti/Crima-Si-Pedeapsa/test/test",
+  "Path": "notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/test/test/notita-2026-03-24-221723.816195.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/test/test/test/notita-2026-03-24-222006.279655.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "notes_folder/Carti/Crima-Si-Pedeapsa/test/test/test",
+  "Path": "notes_folder/notes_folder/Carti/Crima-Si-Pedeapsa/test/test/test/notita-2026-03-24-222006.279655.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/notes_folder/notita-2026-03-24-220159.897156.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "notes_folder",
+  "Path": "notes_folder/notes_folder/notita-2026-03-24-220159.897156.json"
+}

+ 6 - 0
cmds/webservice/bin/notes_folder/test/test2/notita-2026-03-24-233724.186124.json

@@ -0,0 +1,6 @@
+{
+  "titlu": "Untitled",
+  "continut": "",
+  "director": "test/test2",
+  "Path": "notes_folder/test/test2/notita-2026-03-24-233724.186124.json"
+}

+ 2 - 1
cmds/webservice/bin/templates/design.tmpl

@@ -1,7 +1,8 @@
 {{showFile "templates/design/sections/head.tmpl"}}
 <body class="bg-zinc-950 text-zinc-200 h-screen overflow-hidden flex">
 {{showFile "templates/design/sections/nav_small.tmpl"}}
-{{showFile "templates/design/sections/nav_big.tmpl"}}
+
+{{template "nav_big.tmpl" .Folders}}
     
 
     <main class="flex-1 flex flex-col relative bg-zinc-900/20 overflow-auto">

+ 156 - 16
cmds/webservice/bin/templates/design/sections/nav_big.tmpl

@@ -1,19 +1,159 @@
 <aside class="w-64 border-r border-zinc-800 bg-zinc-900/50 flex flex-col">
-        <div class="p-4 flex justify-between items-center border-bottom border-zinc-800">
-            <span class="text-xs font-bold uppercase tracking-widest text-zinc-500">Main Vault</span>
-            <span class="text-[10px] px-1.5 py-0.5 rounded bg-zinc-800 text-zinc-400 border border-zinc-700">v2.4</span>
+    <div class="p-4 flex justify-between items-center border-b border-zinc-800">
+        <span class="text-xs font-bold uppercase tracking-widest text-zinc-500">Main Vault</span>
+        <span class="text-[10px] px-1.5 py-0.5 rounded bg-zinc-800 text-zinc-400 border border-zinc-700">v2.4</span>
+    </div>
+
+    <div class="flex-1 overflow-y-auto custom-scrollbar p-2 space-y-0.5">
+        {{range .Subfoldere}}
+            {{template "folder" .}}
+        {{end}}
+        {{range .Fisiere}}
+            <a href="/notes/?note={{.Path}}"
+               class="flex items-center gap-2 px-2 py-1 text-xs rounded hover:bg-zinc-800 text-zinc-500 hover:text-zinc-300 transition-colors">
+                {{/* File icon */}}
+                <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                     fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
+                     class="shrink-0 text-zinc-600">
+                    <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
+                    <polyline points="14 2 14 8 20 8"/>
+                </svg>
+                <span class="truncate">{{.Nume}}</span>
+            </a>
+        {{end}}
+    </div>
+
+    {{/* BOTTOM: NEW ROOT FOLDER */}}
+    <div class="p-2 border-t border-zinc-800">
+        <form method="POST" action="/api/create_dir" class="flex gap-1 items-center">
+            <input type="hidden" name="director" value="">
+            <input
+                type="text"
+                name="subdirector"
+                placeholder="New folder..."
+                class="flex-1 bg-zinc-800 text-zinc-300 text-xs rounded px-2 py-1 outline-none border border-zinc-700 focus:border-zinc-500 placeholder-zinc-600"
+            >
+            <button type="submit"
+                class="text-zinc-400 hover:text-zinc-100 hover:bg-zinc-700 rounded p-1 transition-colors border border-zinc-700"
+                title="Create folder">
+                {{/* Plus icon */}}
+                <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                     fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                    <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
+                </svg>
+            </button>
+        </form>
+    </div>
+</aside>
+
+
+{{define "folder"}}
+<details open class="group">
+
+    <summary class="flex items-center justify-between px-2 py-1 text-xs rounded hover:bg-zinc-800 cursor-pointer list-none text-zinc-400 group-open:text-zinc-200 transition-colors">
+        <div class="flex items-center gap-1.5 min-w-0">
+            {{/* Chevron */}}
+            <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24"
+                 fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"
+                 class="shrink-0 transition-transform duration-150 group-open:rotate-90">
+                <polyline points="9 18 15 12 9 6"/>
+            </svg>
+
+            {{/* Folder icon — closed */}}
+            <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
+                 class="shrink-0 text-zinc-500 group-open:hidden">
+                <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
+            </svg>
+
+            {{/* Folder icon — open */}}
+            <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
+                 class="shrink-0 text-zinc-300 hidden group-open:block">
+                <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
+                <line x1="2" y1="10" x2="22" y2="10"/>
+            </svg>
+
+            <span class="truncate">{{.Nume}}</span>
         </div>
-        <div class="flex-1 overflow-y-auto custom-scrollbar p-2 space-y-1">
-            <details open class="group">
-                <summary class="flex items-center p-2 text-sm hover:bg-zinc-800 rounded cursor-pointer list-none text-zinc-400 group-open:text-zinc-100">
-                    <span class="mr-2 transform group-open:rotate-90 transition-transform">▸</span> Projects
-                </summary>
-                <div class="pl-6 space-y-1 mt-1 border-l border-zinc-800 ml-3">
-                    <div class="p-2 text-xs bg-indigo-500/10 text-indigo-400 rounded border border-indigo-500/20">System_Architecture.md</div>
-                    <div class="p-2 text-xs hover:bg-zinc-800 rounded text-zinc-500">Database_Schema.sql</div>
-                </div>
-            </details>
-            <div class="p-2 text-sm hover:bg-zinc-800 rounded cursor-pointer text-zinc-400">Daily_Notes</div>
-            <div class="p-2 text-sm hover:bg-zinc-800 rounded cursor-pointer text-zinc-400">Templates</div>
+
+        {{/* ACTION BUTTONS — visible on hover only */}}
+        <div class="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0">
+
+            {{/* New note button */}}
+            <form method="POST" action="/api/save_note">
+                <input type="hidden" name="director" value="{{.Nume}}">
+                <input type="hidden" name="titlu" value="Untitled">
+                <input type="hidden" name="notita" value="">
+                <button type="submit"
+                    onclick="event.stopPropagation()"
+                    class="text-zinc-500 hover:text-zinc-100 hover:bg-zinc-700 rounded p-0.5 transition-colors"
+                    title="New note">
+                    {{/* File plus icon */}}
+                    <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                         fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                        <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
+                        <polyline points="14 2 14 8 20 8"/>
+                        <line x1="12" y1="18" x2="12" y2="12"/>
+                        <line x1="9" y1="15" x2="15" y2="15"/>
+                    </svg>
+                </button>
+            </form>
+
+            {{/* New subfolder button */}}
+            <button
+                onclick="event.stopPropagation(); var f = this.closest('details').querySelector('.new-folder-form'); f.style.display = f.style.display === 'none' ? 'flex' : 'none'; f.querySelector('input[type=text]').focus();"
+                class="text-zinc-500 hover:text-zinc-100 hover:bg-zinc-700 rounded p-0.5 transition-colors"
+                title="New folder">
+                {{/* Folder plus icon */}}
+                <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                     fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                    <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
+                    <line x1="12" y1="13" x2="12" y2="19"/>
+                    <line x1="9" y1="16" x2="15" y2="16"/>
+                </svg>
+            </button>
         </div>
-    </aside>
+    </summary>
+
+    {{/* INLINE FOLDER NAME INPUT */}}
+    <form method="POST" action="/api/create_dir"
+          class="new-folder-form gap-1 px-2 py-1 items-center"
+          style="display:none;">
+        <input type="hidden" name="director" value="{{.Nume}}">
+        <input
+            type="text"
+            name="subdirector"
+            placeholder="Folder name..."
+            class="flex-1 bg-zinc-800 text-zinc-300 text-xs rounded px-2 py-1 outline-none border border-zinc-700 focus:border-zinc-500 placeholder-zinc-600"
+        >
+        <button type="submit"
+            class="text-zinc-400 hover:text-zinc-100 hover:bg-zinc-700 rounded p-1 transition-colors border border-zinc-700">
+            <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24"
+                 fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
+                <polyline points="20 6 9 17 4 12"/>
+            </svg>
+        </button>
+    </form>
+
+    {{/* CHILDREN */}}
+    <div class="ml-3 pl-2 border-l border-zinc-800 space-y-0.5 mt-0.5">
+        {{range .Fisiere}}
+            <a href="/notes/?note={{.Path}}"
+               class="flex items-center gap-2 px-2 py-1 text-xs rounded hover:bg-zinc-800 text-zinc-500 hover:text-zinc-300 transition-colors">
+                <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
+                     fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
+                     class="shrink-0 text-zinc-600">
+                    <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
+                    <polyline points="14 2 14 8 20 8"/>
+                </svg>
+                <span class="truncate">{{.Nume}}</span>
+            </a>
+        {{end}}
+        {{range .Subfoldere}}
+            {{template "folder" .}}
+        {{end}}
+    </div>
+
+</details>
+{{end}}

+ 2 - 2
lib/inout/parser_funcs.go

@@ -8,7 +8,7 @@ import (
 	"text/template"
 )
 
-func getFuncMap() template.FuncMap {
+func GetFuncMap() template.FuncMap {
 	funcMap := template.FuncMap{
 		"showFile":     showFile,
 		"genSeriesInt": genSeriesInt,
@@ -38,7 +38,7 @@ func ParseTemplate(file string, input any) ([]byte, int) {
 	if err != nil {
 		return fmt.Appendf(nil, "%+v", err), http.StatusInternalServerError
 	}
-	tmpl, err := template.New("parse").Funcs(getFuncMap()).Parse(string(b))
+	tmpl, err := template.New("parse").Funcs(GetFuncMap()).Parse(string(b))
 	if err != nil {
 		return fmt.Appendf(nil, "%+v", err), http.StatusInternalServerError
 	}

+ 3 - 1
lib/inout/path.go

@@ -8,6 +8,7 @@ import (
 )
 
 type Folder struct {
+	Display    string
 	Nume       string
 	Fisiere    []File
 	Subfoldere []Folder
@@ -32,10 +33,11 @@ func GetFolderStructure(path string, f *Folder) error {
 		return err
 	}
 	if filepath.Clean(path) != "notes_folder" {
-		f.Nume = filepath.Base(path)
+		f.Nume = strings.TrimPrefix(path, "notes_folder/")
 	} else {
 		f.Nume = "notes_folder"
 	}
+	f.Display = filepath.Base(path)
 	for _, entry := range entries {
 
 		if entry.IsDir() {

+ 68 - 32
lib/server/endpoint_funcs.go

@@ -23,15 +23,11 @@ func Notes(w http.ResponseWriter, r *http.Request, fisier string) {
 	notita := types.Notita{}
 	err := inout.FileToObj(fisier, &notita)
 	if err != nil {
-		w.WriteHeader(http.StatusInternalServerError)
-		w.Write([]byte(WEB_ERR))
-		template.Must(template.ParseFiles("templates/error.tmpl")).Execute(w, err)
+		WriteError(w, err)
 		return
 	}
 	if err := goldmark.Convert([]byte(notita.Continut), &buf); err != nil {
-		w.WriteHeader(http.StatusInternalServerError)
-		w.Write([]byte(WEB_ERR))
-		template.Must(template.ParseFiles("templates/error.tmpl")).Execute(w, err)
+		WriteError(w, err)
 		return
 	}
 	notita.HTML = buf.String()
@@ -46,10 +42,7 @@ func ListNotes(w http.ResponseWriter, r *http.Request, s *Server) {
 		f := inout.Folder{}
 		err := inout.GetFolderStructure(s.NotesDir, &f)
 		if err != nil {
-			resp, code := inout.ParseTemplate("templates/error.tmpl", err)
-			w.Header().Set("Content-Type", "text/html")
-			w.WriteHeader(code)
-			w.Write(resp)
+			WriteError(w, err)
 			return
 		}
 		resp, code := inout.ParseTemplate("templates/list_notes.tmpl", f)
@@ -68,18 +61,15 @@ func EditNotes(w http.ResponseWriter, r *http.Request, filename string) {
 		f := types.Notita{}
 		err := inout.FileToObj(filename, &f)
 		if err != nil {
-			resp, code := inout.ParseTemplate("templates/error.tmpl", err)
-			w.WriteHeader(code)
-			w.Write(resp)
+			WriteError(w, err)
+			return
 		}
 		resp, code := inout.ParseTemplate("templates/edit_notes.tmpl", f)
 		w.WriteHeader(code)
 		w.Write(resp)
 		return
 	}
-	resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("method %s not allowed", r.Method))
-	w.WriteHeader(code)
-	w.Write(resp)
+	WriteError(w, fmt.Errorf("method %s not allowed", r.Method))
 }
 
 func MDToHTML(w http.ResponseWriter, r *http.Request) {
@@ -106,7 +96,8 @@ func MDToHTML(w http.ResponseWriter, r *http.Request) {
 }
 
 func API(w http.ResponseWriter, r *http.Request, s *Server) {
-	action := strings.TrimPrefix(r.URL.Path, "/api/")
+	action := strings.Trim(strings.TrimPrefix(r.URL.Path, "/api/"), "/")
+	fmt.Println(action)
 	if r.Method == "POST" {
 		//w.WriteHeader(http.StatusNotImplemented)
 		//w.Write(fmt.Appendf(nil, "action not implemented: %s", action))
@@ -122,20 +113,14 @@ func API(w http.ResponseWriter, r *http.Request, s *Server) {
 			}
 			err := inout.SafeDir(n.Folder)
 			if err != nil {
-				resp, code := inout.ParseTemplate("templates/error.tmpl", err)
-				w.Header().Set("Content-Type", "text/html")
-				w.WriteHeader(code)
-				w.Write(resp)
+				WriteError(w, err)
 				return
 			}
 			path := filepath.Join(s.NotesDir, n.Folder)
 			err = os.MkdirAll(path, 0755)
 			fmt.Println(n.Folder)
 			if err != nil {
-				resp, code := inout.ParseTemplate("templates/error.tmpl", err)
-				w.Header().Set("Content-Type", "text/html")
-				w.WriteHeader(code)
-				w.Write(resp)
+				WriteError(w, err)
 				return
 			}
 
@@ -146,10 +131,7 @@ func API(w http.ResponseWriter, r *http.Request, s *Server) {
 
 			err = inout.ObjToFile(filepath.Join(s.NotesDir, n.Folder, fisier), n, true)
 			if err != nil {
-				resp, code := inout.ParseTemplate("templates/error.tmpl", err)
-				w.Header().Set("Content-Type", "text/html")
-				w.WriteHeader(code)
-				w.Write(resp)
+				WriteError(w, err)
 				return
 			}
 			referinta := r.Referer()
@@ -169,8 +151,22 @@ func API(w http.ResponseWriter, r *http.Request, s *Server) {
 			fmt.Println(n.Path)
 			err := inout.ObjToFile(n.Path, n, true)
 			if err != nil {
-				w.WriteHeader(http.StatusInternalServerError)
-				fmt.Fprintf(w, "%+v", err)
+				WriteError(w, err)
+				return
+			}
+			referinta := r.Referer()
+			if referinta != "" {
+				http.Redirect(w, r, referinta, http.StatusSeeOther)
+			} else {
+				http.Redirect(w, r, "/index.html", http.StatusSeeOther)
+			}
+		case "create_dir":
+			r.ParseForm()
+			path := filepath.Join("notes_folder", r.Form.Get("director"), r.Form.Get("subdirector"))
+			fmt.Println(path)
+			err := os.Mkdir(path, 0755)
+			if err != nil {
+				WriteError(w, err)
 				return
 			}
 			referinta := r.Referer()
@@ -179,7 +175,6 @@ func API(w http.ResponseWriter, r *http.Request, s *Server) {
 			} else {
 				http.Redirect(w, r, "/index.html", http.StatusSeeOther)
 			}
-
 		}
 	}
 	resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("method %s not allowed", r.Method))
@@ -187,3 +182,44 @@ func API(w http.ResponseWriter, r *http.Request, s *Server) {
 	w.WriteHeader(code)
 	w.Write(resp)
 }
+
+func Design_viewer(w http.ResponseWriter, r *http.Request, s *Server) {
+	f := inout.Folder{}
+	err := inout.GetFolderStructure(s.NotesDir, &f)
+	if err != nil {
+		WriteError(w, err)
+		return
+	}
+	data := struct {
+		Folders inout.Folder
+	}{
+		Folders: f,
+	}
+	renderPage(w, []string{
+		"templates/design.tmpl",
+		"templates/design/sections/nav_big.tmpl",
+	}, data)
+
+}
+
+func WriteError(w http.ResponseWriter, err error) {
+	resp, code := inout.ParseTemplate("templates/error.tmpl", err)
+	w.Header().Set("Content-Type", "text/html")
+	w.WriteHeader(code)
+	w.Write(resp)
+
+}
+
+func renderPage(w http.ResponseWriter, templates []string, data any) {
+	tmpl, err := template.New(filepath.Base(templates[0])).Funcs(inout.GetFuncMap()).ParseFiles(templates...)
+	if err != nil {
+		WriteError(w, err)
+		return
+	}
+	err = tmpl.ExecuteTemplate(w, filepath.Base(templates[0]), data)
+	if err != nil {
+		WriteError(w, err)
+		return
+	}
+
+}

+ 8 - 1
lib/server/handlers.go

@@ -43,7 +43,6 @@ func Wildcard(w http.ResponseWriter, r *http.Request, s *Server) {
 		w.Write(resp)
 		return
 	}
-
 	w.Write(inout.FileToBytes(path))
 }
 func findRoute(path string, routes map[string]string) (string, bool) {
@@ -99,6 +98,14 @@ func makeFuncMap() map[string]hfunc {
 			API(w, r, &srv)
 		},
 		"MKDOWN_CONVERT": MDToHTML,
+		"DESIGN_VIEW": func(w http.ResponseWriter, r *http.Request) {
+			srv := Server{}
+			err := inout.FileToObj("mynotes_cfg.json", &srv)
+			if err != nil {
+				srv.Err = err
+			}
+			Design_viewer(w, r, &srv)
+		},
 	}
 	return handlers
 }