Browse Source

works

master
arnaucode 7 years ago
parent
commit
c77af453f4
8 changed files with 316 additions and 0 deletions
  1. +2
    -0
      .gitignore
  2. +104
    -0
      README.md
  3. +57
    -0
      color.go
  4. +7
    -0
      errors.go
  5. +107
    -0
      fileOperations.go
  6. +39
    -0
      main.go
  7. BIN
      timmy
  8. BIN
      timmy.png

+ 2
- 0
.gitignore

@ -0,0 +1,2 @@
webInput
webOutput

+ 104
- 0
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
<!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
- 0
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
}

+ 7
- 0
errors.go

@ -0,0 +1,7 @@
package main
func check(e error) {
if e != nil {
panic(e)
}
}

+ 107
- 0
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, "<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
- 0
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")
}

BIN
timmy


BIN
timmy.png

Before After
Width: 244  |  Height: 387  |  Size: 72 KiB

Loading…
Cancel
Save