Merge pull request #328 from velour/dynamic-nav

web: remove go template dependency
This commit is contained in:
Chris Sexton 2021-01-09 13:53:23 -05:00 committed by GitHub
commit f1aa4ebeb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 81 additions and 53 deletions

View File

@ -61,7 +61,8 @@ type bot struct {
} }
type EndPoint struct { type EndPoint struct {
Name, URL string Name string `json:"name"`
URL string `json:"url"`
} }
// Variable represents a $var replacement // Variable represents a $var replacement
@ -104,6 +105,7 @@ func New(config *config.Config, connector Connector) Bot {
bot.RefreshPluginWhitelist() bot.RefreshPluginWhitelist()
http.HandleFunc("/", bot.serveRoot) http.HandleFunc("/", bot.serveRoot)
http.HandleFunc("/nav", bot.serveNav)
connector.RegisterEvent(bot.Receive) connector.RegisterEvent(bot.Receive)

View File

@ -1,16 +1,24 @@
package bot package bot
import ( import (
"html/template" "encoding/json"
"fmt"
"net/http" "net/http"
"strings" "strings"
) )
func (b *bot) serveRoot(w http.ResponseWriter, r *http.Request) { func (b *bot) serveRoot(w http.ResponseWriter, r *http.Request) {
context := make(map[string]interface{}) fmt.Fprint(w, rootIndex)
context["Nav"] = b.GetWebNavigation() }
t := template.Must(template.New("rootIndex").Parse(rootIndex))
t.Execute(w, context) func (b *bot) serveNav(w http.ResponseWriter, r *http.Request) {
enc := json.NewEncoder(w)
err := enc.Encode(b.GetWebNavigation())
if err != nil {
jsonErr, _ := json.Marshal(err)
w.WriteHeader(500)
w.Write(jsonErr)
}
} }
// GetWebNavigation returns a list of bootstrap-vue <b-nav-item> links // GetWebNavigation returns a list of bootstrap-vue <b-nav-item> links
@ -51,12 +59,12 @@ var rootIndex = `
<body> <body>
<div id="app"> <div id="app">
<b-navbar> <b-navbar>
<b-navbar-brand>catbase</b-navbar-brand> <b-navbar-brand>catbase</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
</div> </div>
<script> <script>
@ -64,8 +72,15 @@ var rootIndex = `
el: '#app', el: '#app',
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
}, },
mounted: function() {
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
}
}) })
</script> </script>
</body> </body>

View File

@ -5,7 +5,6 @@ package admin
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"os" "os"
"regexp" "regexp"
@ -328,10 +327,8 @@ func (p *AdminPlugin) registerWeb() {
p.bot.RegisterWeb("/vars", "Variables") p.bot.RegisterWeb("/vars", "Variables")
} }
var tpl = template.Must(template.New("factoidIndex").Parse(varIndex))
func (p *AdminPlugin) handleWeb(w http.ResponseWriter, r *http.Request) { func (p *AdminPlugin) handleWeb(w http.ResponseWriter, r *http.Request) {
tpl.Execute(w, struct{ Nav []bot.EndPoint }{p.bot.GetWebNavigation()}) fmt.Fprint(w, varIndex)
} }
func (p *AdminPlugin) handleWebAPI(w http.ResponseWriter, r *http.Request) { func (p *AdminPlugin) handleWebAPI(w http.ResponseWriter, r *http.Request) {

View File

@ -24,7 +24,7 @@ var varIndex = `
<b-navbar> <b-navbar>
<b-navbar-brand>Variables</b-navbar-brand> <b-navbar-brand>Variables</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL" :active="item.Name === 'Variables'">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'Variables'">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<b-alert <b-alert
@ -32,7 +32,7 @@ var varIndex = `
variant="error" variant="error"
v-if="err" v-if="err"
@dismissed="err = ''"> @dismissed="err = ''">
{{ "{{ err }}" }} {{ err }}
</b-alert> </b-alert>
<b-container> <b-container>
<b-table <b-table
@ -48,7 +48,7 @@ var varIndex = `
el: '#app', el: '#app',
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
vars: [], vars: [],
sortBy: 'key', sortBy: 'key',
fields: [ fields: [
@ -58,6 +58,11 @@ var varIndex = `
}, },
mounted() { mounted() {
this.getData(); this.getData();
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
}, },
methods: { methods: {
getData: function() { getData: function() {

View File

@ -5,7 +5,6 @@ package cli
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"time" "time"
@ -91,10 +90,8 @@ func (p *CliPlugin) handleWebAPI(w http.ResponseWriter, r *http.Request) {
w.Write(data) w.Write(data)
} }
var tpl = template.Must(template.New("factoidIndex").Parse(indexHTML))
func (p *CliPlugin) handleWeb(w http.ResponseWriter, r *http.Request) { func (p *CliPlugin) handleWeb(w http.ResponseWriter, r *http.Request) {
tpl.Execute(w, struct{ Nav []bot.EndPoint }{p.bot.GetWebNavigation()}) fmt.Fprint(w, indexHTML)
} }
// Completing the Connector interface, but will not actually be a connector // Completing the Connector interface, but will not actually be a connector

View File

@ -24,14 +24,14 @@ var indexHTML = `
<b-navbar> <b-navbar>
<b-navbar-brand>CLI</b-navbar-brand> <b-navbar-brand>CLI</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL" :active="item.Name === 'CLI'">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'CLI'">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<b-alert <b-alert
dismissable dismissable
variant="error" variant="error"
:show="err"> :show="err">
{{ "{{ err }}" }} {{ err }}
</b-alert> </b-alert>
<b-container> <b-container>
<b-row> <b-row>
@ -80,13 +80,20 @@ var indexHTML = `
el: '#app', el: '#app',
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
answer: '', answer: '',
correct: 0, correct: 0,
textarea: [], textarea: [],
user: '', user: '',
input: '', input: '',
}, },
mounted: function() {
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
},
computed: { computed: {
authenticated: function() { authenticated: function() {
if (this.user !== '') if (this.user !== '')

View File

@ -4,7 +4,6 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template"
"math/rand" "math/rand"
"net/http" "net/http"
"regexp" "regexp"
@ -626,10 +625,8 @@ func (p *CounterPlugin) registerWeb() {
p.Bot.RegisterWeb("/counter", "Counter") p.Bot.RegisterWeb("/counter", "Counter")
} }
var tpl = template.Must(template.New("factoidIndex").Parse(html))
func (p *CounterPlugin) handleCounter(w http.ResponseWriter, r *http.Request) { func (p *CounterPlugin) handleCounter(w http.ResponseWriter, r *http.Request) {
tpl.Execute(w, struct{ Nav []bot.EndPoint }{p.Bot.GetWebNavigation()}) fmt.Fprint(w, html)
} }
func (p *CounterPlugin) handleCounterAPI(w http.ResponseWriter, r *http.Request) { func (p *CounterPlugin) handleCounterAPI(w http.ResponseWriter, r *http.Request) {

View File

@ -22,14 +22,14 @@ var html = `
<b-navbar> <b-navbar>
<b-navbar-brand>Counters</b-navbar-brand> <b-navbar-brand>Counters</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL" :active="item.Name === 'Counter'">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'Counter'">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<b-alert <b-alert
dismissable dismissable
:show="err" :show="err"
variant="error"> variant="error">
{{ "{{ err }}" }} {{ err }}
</b-alert> </b-alert>
<b-container> <b-container>
<b-row> <b-row>
@ -37,14 +37,14 @@ var html = `
<b-col><b-input v-model="answer"></b-col> <b-col><b-input v-model="answer"></b-col>
</b-row> </b-row>
<b-row v-for="(counter, user) in counters"> <b-row v-for="(counter, user) in counters">
{{ "{{ user }}" }}: {{ user }}:
<b-container> <b-container>
<b-row v-for="(count, thing) in counter"> <b-row v-for="(count, thing) in counter">
<b-col offset="1"> <b-col offset="1">
{{ "{{ thing }}" }}: {{ thing }}:
</b-col> </b-col>
<b-col> <b-col>
{{ "{{ count }}" }} {{ count }}
</b-col> </b-col>
<b-col cols="2"> <b-col cols="2">
<button @click="subtract(user,thing,count)">-</button> <button @click="subtract(user,thing,count)">-</button>
@ -72,12 +72,17 @@ var html = `
el: '#app', el: '#app',
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
answer: '', answer: '',
correct: 0, correct: 0,
counters: {} counters: {}
}, },
mounted() { mounted() {
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
axios.get('/counter/api') axios.get('/counter/api')
.then(resp => (this.counters = convertData(resp.data))) .then(resp => (this.counters = convertData(resp.data)))
.catch(err => (this.err = err)); .catch(err => (this.err = err));

View File

@ -842,8 +842,6 @@ func (p *FactoidPlugin) serveAPI(w http.ResponseWriter, r *http.Request) {
w.Write(data) w.Write(data)
} }
var tpl = template.Must(template.New("factoidIndex").Parse(factoidIndex))
func (p *FactoidPlugin) serveQuery(w http.ResponseWriter, r *http.Request) { func (p *FactoidPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
tpl.Execute(w, struct{ Nav []bot.EndPoint }{p.Bot.GetWebNavigation()}) fmt.Fprint(w, factoidIndex)
} }

View File

@ -32,7 +32,7 @@ var factoidIndex = `
<b-navbar> <b-navbar>
<b-navbar-brand>Factoids</b-navbar-brand> <b-navbar-brand>Factoids</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL" :active="item.Name === 'Factoid'">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'Factoid'">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<b-alert <b-alert
@ -40,7 +40,7 @@ var factoidIndex = `
variant="error" variant="error"
v-if="err" v-if="err"
@dismissed="err = ''"> @dismissed="err = ''">
{{ "{{ err }}" }} {{ err }}
</b-alert> </b-alert>
<b-form @submit="runQuery"> <b-form @submit="runQuery">
<b-container> <b-container>
@ -74,7 +74,7 @@ var factoidIndex = `
router, router,
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
query: '', query: '',
results: [], results: [],
fields: [ fields: [
@ -85,6 +85,11 @@ var factoidIndex = `
] ]
}, },
mounted() { mounted() {
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
if (this.$route.query.query) { if (this.$route.query.query) {
this.query = this.$route.query.query; this.query = this.$route.query.query;
this.runQuery() this.runQuery()

View File

@ -80,5 +80,4 @@ func (p *GitPlugin) registerWeb() {
http.HandleFunc("/git/gitea/event", p.giteaEvent) http.HandleFunc("/git/gitea/event", p.giteaEvent)
http.HandleFunc("/git/github/event", p.githubEvent) http.HandleFunc("/git/github/event", p.githubEvent)
http.HandleFunc("/git/gitlab/event", p.gitlabEvent) http.HandleFunc("/git/gitlab/event", p.gitlabEvent)
p.b.RegisterWeb("/git", "Git")
} }

View File

@ -25,7 +25,7 @@ var memeIndex = `
<b-navbar> <b-navbar>
<b-navbar-brand>Memes</b-navbar-brand> <b-navbar-brand>Memes</b-navbar-brand>
<b-navbar-nav> <b-navbar-nav>
<b-nav-item v-for="item in nav" :href="item.URL" :active="item.Name === 'Meme'">{{ "{{ item.Name }}" }}</b-nav-item> <b-nav-item v-for="item in nav" :href="item.url" :active="item.name === 'Meme'">{{ item.name }}</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<b-alert <b-alert
@ -33,7 +33,7 @@ var memeIndex = `
variant="error" variant="error"
v-if="err" v-if="err"
@dismissed="err = ''"> @dismissed="err = ''">
{{ "{{ err }}" }} {{ err }}
</b-alert> </b-alert>
<b-form @submit="addMeme"> <b-form @submit="addMeme">
<b-container> <b-container>
@ -58,7 +58,7 @@ var memeIndex = `
:items="results" :items="results"
:fields="fields"> :fields="fields">
<template v-slot:cell(config)="data"> <template v-slot:cell(config)="data">
<pre>{{ "{{data.item.config}}" }}</pre> <pre>{{data.item.config}}</pre>
</template> </template>
<template v-slot:cell(image)="data"> <template v-slot:cell(image)="data">
<b-img :src="data.item.url" rounded block fluid /> <b-img :src="data.item.url" rounded block fluid />
@ -80,7 +80,7 @@ var memeIndex = `
router, router,
data: { data: {
err: '', err: '',
nav: {{ .Nav }}, nav: [],
name: "", name: "",
url: "", url: "",
config: "", config: "",
@ -93,10 +93,13 @@ var memeIndex = `
] ]
}, },
mounted() { mounted() {
axios.get('/nav')
.then(resp => {
this.nav = resp.data;
})
.catch(err => console.log(err))
this.refresh(); this.refresh();
}, },
computed: {
},
methods: { methods: {
refresh: function() { refresh: function() {
axios.get('/meme/all') axios.get('/meme/all')

View File

@ -3,7 +3,6 @@ package meme
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"html/template"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@ -130,8 +129,7 @@ func (p *MemePlugin) addMeme(w http.ResponseWriter, r *http.Request) {
} }
func (p *MemePlugin) webRoot(w http.ResponseWriter, r *http.Request) { func (p *MemePlugin) webRoot(w http.ResponseWriter, r *http.Request) {
var tpl = template.Must(template.New("factoidIndex").Parse(string(memeIndex))) fmt.Fprint(w, memeIndex)
tpl.Execute(w, struct{ Nav []bot.EndPoint }{p.bot.GetWebNavigation()})
} }
func (p *MemePlugin) img(w http.ResponseWriter, r *http.Request) { func (p *MemePlugin) img(w http.ResponseWriter, r *http.Request) {