Skip to content

Commit

Permalink
Merge pull request #10 from kabukky/development
Browse files Browse the repository at this point in the history
Added: Arguments for plugin helpers.
  • Loading branch information
kabukky committed Apr 25, 2015
2 parents 11db481 + a10fc11 commit 68f8b2f
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 50 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -4,7 +4,7 @@ A blog engine written in Go, compatible with Ghost themes.
![Editor](https://raw.githubusercontent.com/kabukky/journey/gh-pages/images/journey.png)

## About
Please note that Journey is still in alpha and has not been tested in production.
Please note that Journey is still in alpha and has not been tested in production. Not all Ghost theme helpers have been implemented yet so there is bound to be trouble with some Ghost themes. Please open a [New Issue](https://github.com/kabukky/journey/issues) if you encounter a theme that doesn't work.

#### Easy to work with
Create or update your posts from any place and any device. Simply point your browser to yourblog.url/admin/, log in, and start typing away!
Expand Down
10 changes: 10 additions & 0 deletions plugins/conversion.go
Expand Up @@ -2,9 +2,19 @@ package plugins

import (
"github.com/kabukky/journey/structure"
"github.com/kabukky/journey/structure/methods"
"github.com/yuin/gopher-lua"
)

func convertArguments(vm *lua.LState, structureArguments []structure.Helper) *lua.LTable {
table := vm.NewTable()
arguments := methods.ProcessHelperArguments(structureArguments)
for key, value := range arguments {
table.RawSet(lua.LString(key), lua.LString(value))
}
return table
}

func convertPost(vm *lua.LState, structurePost *structure.Post) *lua.LTable {
post := vm.NewTable()
post.RawSet(lua.LString("id"), lua.LNumber(structurePost.Id))
Expand Down
8 changes: 4 additions & 4 deletions plugins/execution.go
Expand Up @@ -6,13 +6,13 @@ import (
"log"
)

func Execute(name string, values *structure.RequestData) ([]byte, error) {
func Execute(helper *structure.Helper, values *structure.RequestData) ([]byte, error) {
// Retrieve the lua state
vm := values.PluginVMs[name]
vm := values.PluginVMs[helper.Name]
// Execute plugin
err := vm.CallByParam(lua.P{Fn: vm.GetGlobal(name), NRet: 1, Protect: true})
err := vm.CallByParam(lua.P{Fn: vm.GetGlobal(helper.Name), NRet: 1, Protect: true})
if err != nil {
log.Println("Error while executing plugin for helper "+name+":", err)
log.Println("Error while executing plugin for helper "+helper.Name+":", err)
// Since the vm threw an error, close all vms and don't put the map back into the pool
for _, luavm := range values.PluginVMs {
luavm.Close()
Expand Down
10 changes: 8 additions & 2 deletions plugins/loading.go
Expand Up @@ -56,12 +56,13 @@ func getHelperNames(fileName string) ([]string, error) {
defer vm.Close()
// Set up vm functions
values := &structure.RequestData{}
helper := &structure.Helper{}
absDir, err := filepath.Abs(fileName)
if err != nil {
log.Println("Error while determining absolute path to lua file:", err)
return helperList, err
}
setUpVm(vm, values, absDir)
setUpVm(vm, helper, values, absDir)
// Execute plugin
// TODO: Is there a better way to just load the file? We only need to execute the register function (see below)
err = vm.DoFile(absDir)
Expand Down Expand Up @@ -91,7 +92,7 @@ func getHelperNames(fileName string) ([]string, error) {
}

// Creates all methods that can be used from Lua.
func setUpVm(vm *lua.LState, values *structure.RequestData, absPathToLuaFile string) {
func setUpVm(vm *lua.LState, helper *structure.Helper, values *structure.RequestData, absPathToLuaFile string) {
luaPath := filepath.Dir(absPathToLuaFile)
// Function to get the directory of the current file (to add to LUA_PATH in Lua)
vm.SetGlobal("getCurrentDir", vm.NewFunction(func(vm *lua.LState) int {
Expand All @@ -103,6 +104,11 @@ func setUpVm(vm *lua.LState, values *structure.RequestData, absPathToLuaFile str
log.Println(vm.Get(-1).String())
return 0 // Number of results
}))
// Function to get helper arguments
vm.SetGlobal("getArguments", vm.NewFunction(func(vm *lua.LState) int {
vm.Push(convertArguments(vm, helper.Arguments))
return 1 // Number of results
}))
// Function to get number of posts in values
vm.SetGlobal("getNumberOfPosts", vm.NewFunction(func(vm *lua.LState) int {
vm.Push(lua.LNumber(len(values.Posts)))
Expand Down
6 changes: 3 additions & 3 deletions plugins/luapool.go
Expand Up @@ -15,23 +15,23 @@ type lStatePool struct {
saved []map[string]*lua.LState
}

func (pl *lStatePool) Get(values *structure.RequestData) map[string]*lua.LState {
func (pl *lStatePool) Get(helper *structure.Helper, values *structure.RequestData) map[string]*lua.LState {
pl.m.Lock()
defer pl.m.Unlock()
n := len(pl.saved)
if n == 0 {
x := pl.New()
// Since these are new lua states, do the lua file.
for key, value := range x {
setUpVm(value, values, LuaPool.files[key])
setUpVm(value, helper, values, LuaPool.files[key])
value.DoFile(LuaPool.files[key])
}
return x
}
x := pl.saved[n-1]
// Set the new values for this request in every lua state
for key, value := range x {
setUpVm(value, values, LuaPool.files[key])
setUpVm(value, helper, values, LuaPool.files[key])
}
pl.saved = pl.saved[0 : n-1]
return x
Expand Down
20 changes: 20 additions & 0 deletions structure/methods/helper.go
@@ -0,0 +1,20 @@
package methods

import (
"github.com/kabukky/journey/structure"
"strings"
)

func ProcessHelperArguments(arguments []structure.Helper) map[string]string {
argumentsMap := make(map[string]string)
for index, _ := range arguments {
// Separate = arguments and put them in map
argumentParts := strings.SplitN(arguments[index].Name, "=", 2)
if len(argumentParts) > 1 {
argumentsMap[argumentParts[0]] = argumentParts[1]
} else {
argumentsMap[arguments[index].Name] = ""
}
}
return argumentsMap
}
74 changes: 34 additions & 40 deletions templates/handlebars.go
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/kabukky/journey/filenames"
"github.com/kabukky/journey/plugins"
"github.com/kabukky/journey/structure"
"github.com/kabukky/journey/structure/methods"
"html"
"log"
"net/url"
Expand All @@ -22,16 +23,20 @@ var jqueryCodeForFooter = []byte("<script src=\"" + filenames.JqueryFilename + "
func nullFunc(helper *structure.Helper, values *structure.RequestData) []byte {
// Check if the helper was defined in a plugin
if plugins.LuaPool != nil {
// Get a state map to execute and attach it to the requestdata
// Get a state map to execute and attach it to the request data
if values.PluginVMs == nil {
values.PluginVMs = plugins.LuaPool.Get(values)
values.PluginVMs = plugins.LuaPool.Get(helper, values)
}
if values.PluginVMs[helper.Name] != nil {
pluginResult, err := plugins.Execute(helper.Name, values)
pluginResult, err := plugins.Execute(helper, values)
if err != nil {
return []byte{}
}
return evaluateEscape(pluginResult, helper.Unescaped)
} else {
// This helper is not implemented in a plugin. Get rid of the Lua VMs
plugins.LuaPool.Put(values.PluginVMs)
values.PluginVMs = nil
}
}
//log.Println("Warning: This helper is not implemented:", helper.Name)
Expand Down Expand Up @@ -60,24 +65,28 @@ func paginationDotTotalFunc(helper *structure.Helper, values *structure.RequestD
}

func pluralFunc(helper *structure.Helper, values *structure.RequestData) []byte {
countString := string(helper.Arguments[0].Function(helper, values))
if countString == "" {
log.Println("Couldn't get count in plural helper")
return []byte{}
}
for _, argument := range helper.Arguments[1:] {
if countString == "0" && strings.HasPrefix(argument.Name, "empty") {
output := argument.Name[len("empty"):]
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
} else if countString == "1" && strings.HasPrefix(argument.Name, "singular") {
output := argument.Name[len("singular"):]
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
} else if countString != "0" && countString != "1" && strings.HasPrefix(argument.Name, "plural") {
output := argument.Name[len("plural"):]
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
if len(helper.Arguments) != 0 {
// Get the number calculated by executing the first argument
countString := string(helper.Arguments[0].Function(helper, values))
if countString == "" {
log.Println("Couldn't get count in plural helper")
return []byte{}
}
arguments := methods.ProcessHelperArguments(helper.Arguments)
for key, value := range arguments {
if countString == "0" && key == "empty" {
output := value
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
} else if countString == "1" && key == "singular" {
output := value
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
} else if countString != "0" && countString != "1" && key == "plural" {
output := value
output = strings.Replace(output, "%", countString, -1)
return []byte(output)
}
}
}
return []byte{}
Expand Down Expand Up @@ -420,7 +429,7 @@ func tagsFunc(helper *structure.Helper, values *structure.RequestData) []byte {
prefix := ""
makeLink := true
if len(helper.Arguments) != 0 {
arguments := processArguments(helper.Arguments)
arguments := methods.ProcessHelperArguments(helper.Arguments)
for key, value := range arguments {
if key == "separator" {
separator = value
Expand Down Expand Up @@ -483,7 +492,7 @@ func post_classFunc(helper *structure.Helper, values *structure.RequestData) []b
func urlFunc(helper *structure.Helper, values *structure.RequestData) []byte {
var buffer bytes.Buffer
if len(helper.Arguments) != 0 {
arguments := processArguments(helper.Arguments)
arguments := methods.ProcessHelperArguments(helper.Arguments)
for key, value := range arguments {
if key == "absolute" {
if value == "true" {
Expand Down Expand Up @@ -519,7 +528,7 @@ func contentFunc(helper *structure.Helper, values *structure.RequestData) []byte
func excerptFunc(helper *structure.Helper, values *structure.RequestData) []byte {
if values.CurrentHelperContext == 1 { // post
if len(helper.Arguments) != 0 {
arguments := processArguments(helper.Arguments)
arguments := methods.ProcessHelperArguments(helper.Arguments)
for key, value := range arguments {
if key == "words" {
number, err := strconv.Atoi(value)
Expand Down Expand Up @@ -564,7 +573,7 @@ func dateFunc(helper *structure.Helper, values *structure.RequestData) []byte {
}
// Get the date
if len(helper.Arguments) != 0 {
arguments := processArguments(helper.Arguments)
arguments := methods.ProcessHelperArguments(helper.Arguments)
for key, value := range arguments {
if key == "published_at" {
showPublicationDate = true
Expand Down Expand Up @@ -852,7 +861,6 @@ func atBlogDotTitleFunc(helper *structure.Helper, values *structure.RequestData)

func atBlogDotUrlFunc(helper *structure.Helper, values *structure.RequestData) []byte {
var buffer bytes.Buffer
log.Println(string(values.Blog.Url))
buffer.Write(values.Blog.Url)
return evaluateEscape(buffer.Bytes(), helper.Unescaped)
}
Expand All @@ -875,17 +883,3 @@ func evaluateEscape(value []byte, unescaped bool) []byte {
}
return []byte(html.EscapeString(string(value)))
}

func processArguments(arguments []structure.Helper) map[string]string {
argumentsMap := make(map[string]string)
for index, _ := range arguments {
// Separate = arguments and put them in map
argumentParts := strings.SplitN(arguments[index].Name, "=", 2)
if len(argumentParts) > 1 {
argumentsMap[argumentParts[0]] = argumentParts[1]
} else {
argumentsMap[arguments[index].Name] = ""
}
}
return argumentsMap
}

0 comments on commit 68f8b2f

Please sign in to comment.