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