diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5e5974 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +webInput +webOutput diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf77d70 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# Timmy [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucode/timmy)](https://goreportcard.com/report/github.com/arnaucode/timmy) + +web templating engine for static websites, written in Go lang + + +![timmy](https://raw.githubusercontent.com/arnaucode/timmy/master/timmy.png "timmy") + + +## Example + +- Simple project structure example: + +``` +webInput/ + index.html + templates/ + userTemplate.html + userTemplate.json +``` + +- Set the html file: + +```html + + + + +

My First Heading

+ +

My first paragraph.

+ + + + + + +``` + + +- Set the template file: + +```html +
+
{{username}}
+
{{description}}
+
{{phone}}
+
+``` + +- 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 + + + + +

My First Heading

+

My first paragraph.

+
+
Michaela Doe
+
Hi, I'm here to code
+
456456456
+
+
+
John Doe
+
Hi, I'm here
+
123456789
+
+
+
Myself
+
How are you
+
no phone
+
+ + + +``` diff --git a/color.go b/color.go new file mode 100644 index 0000000..e945ac5 --- /dev/null +++ b/color.go @@ -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 +} diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..d9f9f75 --- /dev/null +++ b/errors.go @@ -0,0 +1,7 @@ +package main + +func check(e error) { + if e != nil { + panic(e) + } +} diff --git a/fileOperations.go b/fileOperations.go new file mode 100644 index 0000000..71fabf5 --- /dev/null +++ b/fileOperations.go @@ -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, "", "", -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, "") { + 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) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..bd34bec --- /dev/null +++ b/main.go @@ -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") +} diff --git a/timmy b/timmy new file mode 100755 index 0000000..19b8712 Binary files /dev/null and b/timmy differ diff --git a/timmy.png b/timmy.png new file mode 100644 index 0000000..053f72b Binary files /dev/null and b/timmy.png differ