mirror of
https://github.com/arnaucube/konstrui.git
synced 2026-02-07 11:36:40 +01:00
works
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
webInput
|
||||||
|
webOutput
|
||||||
104
README.md
Normal file
104
README.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# Timmy [](https://goreportcard.com/report/github.com/arnaucode/timmy)
|
||||||
|
|
||||||
|
web templating engine for static websites, written in Go lang
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
- Simple project structure example:
|
||||||
|
|
||||||
|
```
|
||||||
|
webInput/
|
||||||
|
index.html
|
||||||
|
templates/
|
||||||
|
userTemplate.html
|
||||||
|
userTemplate.json
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the html file:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>My First Heading</h1>
|
||||||
|
|
||||||
|
<p>My first paragraph.</p>
|
||||||
|
|
||||||
|
<timmy-template html="templates/userTemplate.html" data="templates/userTemplate.json"></timmy-template>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
- Set the template file:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="class1">
|
||||||
|
<div class="class2">{{username}}</div>
|
||||||
|
<div class="class2">{{description}}</div>
|
||||||
|
<div class="class2">{{phone}}</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the template data file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[{
|
||||||
|
"username": "Michaela Doe",
|
||||||
|
"description": "Hi, I'm here to code",
|
||||||
|
"phone": "456456456"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "John Doe",
|
||||||
|
"description": "Hi, I'm here",
|
||||||
|
"phone": "123456789"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username": "Myself",
|
||||||
|
"description": "How are you",
|
||||||
|
"phone": "no phone"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- Execute Timmy
|
||||||
|
|
||||||
|
```
|
||||||
|
./timmy
|
||||||
|
```
|
||||||
|
|
||||||
|
- Output:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>My First Heading</h1>
|
||||||
|
<p>My first paragraph.</p>
|
||||||
|
<div class="class1">
|
||||||
|
<div class="class2">Michaela Doe</div>
|
||||||
|
<div class="class2">Hi, I'm here to code</div>
|
||||||
|
<div class="class2">456456456</div>
|
||||||
|
</div>
|
||||||
|
<div class="class1">
|
||||||
|
<div class="class2">John Doe</div>
|
||||||
|
<div class="class2">Hi, I'm here</div>
|
||||||
|
<div class="class2">123456789</div>
|
||||||
|
</div>
|
||||||
|
<div class="class1">
|
||||||
|
<div class="class2">Myself</div>
|
||||||
|
<div class="class2">How are you</div>
|
||||||
|
<div class="class2">no phone</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
```
|
||||||
57
color.go
Normal file
57
color.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
//Color struct, defines the color
|
||||||
|
type Color struct{}
|
||||||
|
|
||||||
|
var c Color
|
||||||
|
|
||||||
|
//DarkGray color
|
||||||
|
func (c Color) DarkGray(t string) {
|
||||||
|
fmt.Print("\x1b[30;1m") //dark gray
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Red color
|
||||||
|
func (c Color) Red(t string) {
|
||||||
|
fmt.Print("\x1b[31;1m") //red
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Green color
|
||||||
|
func (c Color) Green(t string) {
|
||||||
|
fmt.Print("\x1b[32;1m") //green
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Yellow color
|
||||||
|
func (c Color) Yellow(t string) {
|
||||||
|
fmt.Print("\x1b[33;1m") //yellow
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Blue color
|
||||||
|
func (c Color) Blue(t string) {
|
||||||
|
fmt.Print("\x1b[34;1m") //blue
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Purple color
|
||||||
|
func (c Color) Purple(t string) {
|
||||||
|
fmt.Print("\x1b[35;1m") //purple
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cyan color
|
||||||
|
func (c Color) Cyan(t string) {
|
||||||
|
fmt.Print("\x1b[36;1m") //cyan
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
7
errors.go
Normal file
7
errors.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
107
fileOperations.go
Normal file
107
fileOperations.go
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
//dataEntry is the map used to create the array of maps, where the templatejson data is stored
|
||||||
|
type dataEntry map[string]string
|
||||||
|
|
||||||
|
func readFile(folderPath string, filename string) string {
|
||||||
|
dat, err := ioutil.ReadFile(folderPath + "/" + filename)
|
||||||
|
check(err)
|
||||||
|
return string(dat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDataFromJson(path string) []dataEntry {
|
||||||
|
var entries []dataEntry
|
||||||
|
file, err := ioutil.ReadFile(path)
|
||||||
|
check(err)
|
||||||
|
content := string(file)
|
||||||
|
var rawEntries []*json.RawMessage
|
||||||
|
json.Unmarshal([]byte(content), &rawEntries)
|
||||||
|
for i := 0; i < len(rawEntries); i++ {
|
||||||
|
rawEntryMarshaled, err := json.Marshal(rawEntries[i])
|
||||||
|
check(err)
|
||||||
|
var newDataEntry map[string]string
|
||||||
|
json.Unmarshal(rawEntryMarshaled, &newDataEntry)
|
||||||
|
entries = append(entries, newDataEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateFromTemplateAndData(templateContent string, entries []dataEntry) string {
|
||||||
|
|
||||||
|
var newContent string
|
||||||
|
|
||||||
|
for i := 0; i < len(entries); i++ {
|
||||||
|
var entryContent string
|
||||||
|
entryContent = templateContent
|
||||||
|
//first, get the map keys
|
||||||
|
var keys []string
|
||||||
|
for key, _ := range entries[i] {
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
//now, replace the keys with the values
|
||||||
|
for j := 0; j < len(keys); j++ {
|
||||||
|
entryContent = strings.Replace(entryContent, "{{"+keys[j]+"}}", entries[i][keys[j]], -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
newContent = newContent + entryContent
|
||||||
|
}
|
||||||
|
return newContent
|
||||||
|
}
|
||||||
|
func getTemplateParameters(line string) (string, string) {
|
||||||
|
var templatePath string
|
||||||
|
var data string
|
||||||
|
line = strings.Replace(line, "<timmy-template ", "", -1)
|
||||||
|
line = strings.Replace(line, "></timmy-template>", "", -1)
|
||||||
|
attributes := strings.Split(line, " ")
|
||||||
|
//fmt.Println(attributes)
|
||||||
|
for i := 0; i < len(attributes); i++ {
|
||||||
|
attSplitted := strings.Split(attributes[i], "=")
|
||||||
|
if attSplitted[0] == "html" {
|
||||||
|
templatePath = strings.Replace(attSplitted[1], `"`, "", -1)
|
||||||
|
}
|
||||||
|
if attSplitted[0] == "data" {
|
||||||
|
data = strings.Replace(attSplitted[1], `"`, "", -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return templatePath, data
|
||||||
|
}
|
||||||
|
|
||||||
|
func useTemplate(templatePath string, dataPath string) string {
|
||||||
|
templateContent := readFile(rawFolderPath, templatePath)
|
||||||
|
entries := getDataFromJson(rawFolderPath + "/" + dataPath)
|
||||||
|
generated := generateFromTemplateAndData(templateContent, entries)
|
||||||
|
return generated
|
||||||
|
}
|
||||||
|
|
||||||
|
func putTemplates(folderPath string, filename string) string {
|
||||||
|
var fileContent string
|
||||||
|
f, err := os.Open(folderPath + "/" + filename)
|
||||||
|
check(err)
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
lineCount := 1
|
||||||
|
for scanner.Scan() {
|
||||||
|
currentLine := scanner.Text()
|
||||||
|
if strings.Contains(currentLine, "<timmy-template") && strings.Contains(currentLine, "</timmy-template>") {
|
||||||
|
templatePath, data := getTemplateParameters(currentLine)
|
||||||
|
fileContent = fileContent + useTemplate(templatePath, data)
|
||||||
|
} else {
|
||||||
|
fileContent = fileContent + currentLine
|
||||||
|
}
|
||||||
|
lineCount++
|
||||||
|
}
|
||||||
|
return fileContent
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFile(path string, newContent string) {
|
||||||
|
err := ioutil.WriteFile(path, []byte(newContent), 0644)
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
39
main.go
Normal file
39
main.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const rawFolderPath = "./webInput"
|
||||||
|
const newFolderPath = "./webOutput"
|
||||||
|
|
||||||
|
func parseDir(folderPath string, newDir string) {
|
||||||
|
files, _ := ioutil.ReadDir(folderPath)
|
||||||
|
for _, f := range files {
|
||||||
|
fileNameSplitted := strings.Split(f.Name(), ".")
|
||||||
|
extension := fileNameSplitted[len(fileNameSplitted)-1]
|
||||||
|
if extension == "html" {
|
||||||
|
fileContent := putTemplates(folderPath, f.Name())
|
||||||
|
writeFile(newDir+"/"+f.Name(), fileContent)
|
||||||
|
} else if extension == "css" {
|
||||||
|
fileContent := readFile(folderPath, f.Name())
|
||||||
|
writeFile(newDir+"/"+f.Name(), fileContent)
|
||||||
|
}
|
||||||
|
if len(fileNameSplitted) == 1 {
|
||||||
|
newDir := newDir + "/" + f.Name()
|
||||||
|
oldDir := rawFolderPath + "/" + f.Name()
|
||||||
|
if _, err := os.Stat(newDir); os.IsNotExist(err) {
|
||||||
|
_ = os.Mkdir(newDir, 0700)
|
||||||
|
}
|
||||||
|
parseDir(oldDir, newDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
c.Green("getting files from /webInput")
|
||||||
|
c.Green("templating")
|
||||||
|
parseDir(rawFolderPath, newFolderPath)
|
||||||
|
c.Green("webpage finished, wiles at /webOutput")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user