Add bookmarklet
This commit is contained in:
parent
1bc43ec2bc
commit
6690f6a70e
26 changed files with 244 additions and 48 deletions
|
@ -26,7 +26,7 @@ TODO
|
|||
|
||||
- [ ] Custom entries sorting
|
||||
- [ ] Webpage scraper (Readability)
|
||||
- [ ] Bookmarklet
|
||||
- [X] Bookmarklet
|
||||
- [ ] External integrations (Pinboard, Wallabag...)
|
||||
- [ ] Gzip compression
|
||||
- [ ] Integration tests
|
||||
|
|
|
@ -9,6 +9,10 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultBaseURL = "http://localhost"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.495654213 -0800 PST m=+0.041889871
|
||||
// 2017-11-21 19:31:59.645632989 -0800 PST m=+0.024631837
|
||||
|
||||
package locale
|
||||
|
||||
|
@ -139,12 +139,17 @@ var Translations = map[string]string{
|
|||
"Work in progress...": "Travail en cours...",
|
||||
"This user already exists.": "Cet utilisateur existe déjà.",
|
||||
"This category already exists.": "Cette catégorie existe déjà.",
|
||||
"Unable to update this category.": "Impossible de mettre à jour cette catégorie."
|
||||
"Unable to update this category.": "Impossible de mettre à jour cette catégorie.",
|
||||
"Integrations": "Intégrations",
|
||||
"Bookmarklet": "Bookmarklet",
|
||||
"Drag and drop this link to your bookmarks.": "Glisser-déposer ce lien dans vos favoris.",
|
||||
"This special link allows you to subscribe to a website directly by using a bookmark in your web browser.": "Ce lien spécial vous permet de vous abonner à un site web directement en utilisant un marque page dans votre navigateur web.",
|
||||
"Add to Miniflux": "Ajouter à Miniflux"
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
||||
var TranslationsChecksums = map[string]string{
|
||||
"en_US": "6fe95384260941e8a5a3c695a655a932e0a8a6a572c1e45cb2b1ae8baa01b897",
|
||||
"fr_FR": "5c8c2c5e35a17a7dd3c30596b73342f70950a3bbce00786d43ccba01b96ea672",
|
||||
"fr_FR": "f1ddbcfb8ffd837a2df69e8506d023e4254ead2f0b94e518ab595df97d32c87a",
|
||||
}
|
||||
|
|
|
@ -123,5 +123,10 @@
|
|||
"Work in progress...": "Travail en cours...",
|
||||
"This user already exists.": "Cet utilisateur existe déjà.",
|
||||
"This category already exists.": "Cette catégorie existe déjà.",
|
||||
"Unable to update this category.": "Impossible de mettre à jour cette catégorie."
|
||||
"Unable to update this category.": "Impossible de mettre à jour cette catégorie.",
|
||||
"Integrations": "Intégrations",
|
||||
"Bookmarklet": "Bookmarklet",
|
||||
"Drag and drop this link to your bookmarks.": "Glisser-déposer ce lien dans vos favoris.",
|
||||
"This special link allows you to subscribe to a website directly by using a bookmark in your web browser.": "Ce lien spécial vous permet de vous abonner à un site web directement en utilisant un marque page dans votre navigateur web.",
|
||||
"Add to Miniflux": "Ajouter à Miniflux"
|
||||
}
|
||||
|
|
|
@ -18,16 +18,19 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// HandlerFunc is an application HTTP handler.
|
||||
type HandlerFunc func(ctx *Context, request *Request, response *Response)
|
||||
|
||||
// Handler manages HTTP handlers and middlewares.
|
||||
type Handler struct {
|
||||
store *storage.Storage
|
||||
translator *locale.Translator
|
||||
template *template.TemplateEngine
|
||||
template *template.Engine
|
||||
router *mux.Router
|
||||
middleware *middleware.MiddlewareChain
|
||||
}
|
||||
|
||||
// Use is a wrapper around an HTTP handler.
|
||||
func (h *Handler) Use(f HandlerFunc) http.Handler {
|
||||
return h.middleware.WrapFunc(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
defer helper.ExecutionTime(time.Now(), r.URL.Path)
|
||||
|
@ -47,7 +50,8 @@ func (h *Handler) Use(f HandlerFunc) http.Handler {
|
|||
}))
|
||||
}
|
||||
|
||||
func NewHandler(store *storage.Storage, router *mux.Router, template *template.TemplateEngine, translator *locale.Translator, middleware *middleware.MiddlewareChain) *Handler {
|
||||
// NewHandler returns a new Handler.
|
||||
func NewHandler(store *storage.Storage, router *mux.Router, template *template.Engine, translator *locale.Translator, middleware *middleware.MiddlewareChain) *Handler {
|
||||
return &Handler{
|
||||
store: store,
|
||||
translator: translator,
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
type HTMLResponse struct {
|
||||
writer http.ResponseWriter
|
||||
request *http.Request
|
||||
template *template.TemplateEngine
|
||||
template *template.Engine
|
||||
}
|
||||
|
||||
// Render execute a template and send to the client the generated HTML.
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
type Response struct {
|
||||
writer http.ResponseWriter
|
||||
request *http.Request
|
||||
template *template.TemplateEngine
|
||||
template *template.Engine
|
||||
}
|
||||
|
||||
// SetCookie send a cookie to the client.
|
||||
|
@ -67,6 +67,6 @@ func (r *Response) commonHeaders() {
|
|||
}
|
||||
|
||||
// NewResponse returns a new Response.
|
||||
func NewResponse(w http.ResponseWriter, r *http.Request, template *template.TemplateEngine) *Response {
|
||||
func NewResponse(w http.ResponseWriter, r *http.Request, template *template.Engine) *Response {
|
||||
return &Response{writer: w, request: r, template: template}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package server
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/miniflux/miniflux2/config"
|
||||
"github.com/miniflux/miniflux2/locale"
|
||||
"github.com/miniflux/miniflux2/reader/feed"
|
||||
"github.com/miniflux/miniflux2/reader/opml"
|
||||
|
@ -20,10 +21,10 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
|
||||
func getRoutes(cfg *config.Config, store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
|
||||
router := mux.NewRouter()
|
||||
translator := locale.Load()
|
||||
templateEngine := template.NewTemplateEngine(router, translator)
|
||||
templateEngine := template.NewEngine(cfg, router, translator)
|
||||
|
||||
apiController := api_controller.NewController(store, feedHandler)
|
||||
uiController := ui_controller.NewController(store, feedHandler, opml.NewHandler(store))
|
||||
|
@ -110,6 +111,9 @@ func getRoutes(store *storage.Storage, feedHandler *feed.Handler) *mux.Router {
|
|||
router.Handle("/settings", uiHandler.Use(uiController.ShowSettings)).Name("settings").Methods("GET")
|
||||
router.Handle("/settings", uiHandler.Use(uiController.UpdateSettings)).Name("updateSettings").Methods("POST")
|
||||
|
||||
router.Handle("/bookmarklet", uiHandler.Use(uiController.Bookmarklet)).Name("bookmarklet").Methods("GET")
|
||||
router.Handle("/integrations", uiHandler.Use(uiController.ShowIntegrations)).Name("integrations").Methods("GET")
|
||||
|
||||
router.Handle("/sessions", uiHandler.Use(uiController.ShowSessions)).Name("sessions").Methods("GET")
|
||||
router.Handle("/sessions/{sessionID}/remove", uiHandler.Use(uiController.RemoveSession)).Name("removeSession").Methods("POST")
|
||||
|
||||
|
|
|
@ -5,21 +5,23 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/miniflux/miniflux2/config"
|
||||
"github.com/miniflux/miniflux2/reader/feed"
|
||||
"github.com/miniflux/miniflux2/storage"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/miniflux/miniflux2/config"
|
||||
"github.com/miniflux/miniflux2/reader/feed"
|
||||
"github.com/miniflux/miniflux2/storage"
|
||||
)
|
||||
|
||||
// NewServer returns a new HTTP server.
|
||||
func NewServer(cfg *config.Config, store *storage.Storage, feedHandler *feed.Handler) *http.Server {
|
||||
server := &http.Server{
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
Addr: cfg.Get("LISTEN_ADDR", "127.0.0.1:8080"),
|
||||
Handler: getRoutes(store, feedHandler),
|
||||
Handler: getRoutes(cfg, store, feedHandler),
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.461181295 -0800 PST m=+0.007416953
|
||||
// 2017-11-21 19:31:59.626742594 -0800 PST m=+0.005741442
|
||||
|
||||
package static
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -659,3 +659,18 @@ a.button {
|
|||
.loading {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Bookmarlet */
|
||||
.bookmarklet {
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 5px;
|
||||
padding: 15px;
|
||||
margin: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bookmarklet a {
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.4687788 -0800 PST m=+0.015014458
|
||||
// 2017-11-21 19:31:59.631783539 -0800 PST m=+0.010782387
|
||||
|
||||
package static
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.491806442 -0800 PST m=+0.038042100
|
||||
// 2017-11-21 19:31:59.643994492 -0800 PST m=+0.022993340
|
||||
|
||||
package template
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
|
35
server/template/html/integrations.html
Normal file
35
server/template/html/integrations.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
{{ define "title"}}{{ t "Integrations" }}{{ end }}
|
||||
|
||||
{{ define "content"}}
|
||||
<section class="page-header">
|
||||
<h1>{{ t "Integrations" }}</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
{{ if .user.IsAdmin }}
|
||||
<li>
|
||||
<a href="{{ route "users" }}">{{ t "Users" }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
<li>
|
||||
<a href="{{ route "about" }}">{{ t "About" }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="panel">
|
||||
<h3>{{ t "Bookmarklet" }}</h3>
|
||||
<p>{{ t "This special link allows you to subscribe to a website directly by using a bookmark in your web browser." }}</p>
|
||||
|
||||
<div class="bookmarklet">
|
||||
<a href="javascript:location.href='{{ baseURL }}{{ route "bookmarklet" }}?uri='+encodeURIComponent(window.location.href)">{{ t "Add to Miniflux" }}</a>
|
||||
</div>
|
||||
|
||||
<p>{{ t "Drag and drop this link to your bookmarks." }}</p>
|
||||
</div>
|
||||
|
||||
{{ end }}
|
|
@ -7,6 +7,9 @@
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "users" }}">{{ t "Users" }}</a>
|
||||
</li>
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
<section class="page-header">
|
||||
<h1>{{ t "Settings" }}</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Copyright 2017 Frédéric Guilloe. All rights reserved.
|
||||
// Use of this source code is governed by the Apache 2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -13,6 +13,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miniflux/miniflux2/config"
|
||||
"github.com/miniflux/miniflux2/errors"
|
||||
"github.com/miniflux/miniflux2/locale"
|
||||
"github.com/miniflux/miniflux2/server/route"
|
||||
|
@ -22,23 +23,28 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type TemplateEngine struct {
|
||||
// Engine handles the templating system.
|
||||
type Engine struct {
|
||||
templates map[string]*template.Template
|
||||
router *mux.Router
|
||||
translator *locale.Translator
|
||||
currentLocale *locale.Language
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
func (t *TemplateEngine) ParseAll() {
|
||||
func (e *Engine) parseAll() {
|
||||
funcMap := template.FuncMap{
|
||||
"baseURL": func() string {
|
||||
return e.cfg.Get("BASE_URL", config.DefaultBaseURL)
|
||||
},
|
||||
"route": func(name string, args ...interface{}) string {
|
||||
return route.GetRoute(t.router, name, args...)
|
||||
return route.GetRoute(e.router, name, args...)
|
||||
},
|
||||
"noescape": func(str string) template.HTML {
|
||||
return template.HTML(str)
|
||||
},
|
||||
"proxyFilter": func(data string) string {
|
||||
return filter.ImageProxyFilter(t.router, data)
|
||||
return filter.ImageProxyFilter(e.router, data)
|
||||
},
|
||||
"domain": func(websiteURL string) string {
|
||||
parsedURL, err := url.Parse(websiteURL)
|
||||
|
@ -58,15 +64,15 @@ func (t *TemplateEngine) ParseAll() {
|
|||
return ts.Format("2006-01-02 15:04:05")
|
||||
},
|
||||
"elapsed": func(ts time.Time) string {
|
||||
return helper.GetElapsedTime(t.currentLocale, ts)
|
||||
return helper.GetElapsedTime(e.currentLocale, ts)
|
||||
},
|
||||
"t": func(key interface{}, args ...interface{}) string {
|
||||
switch key.(type) {
|
||||
case string:
|
||||
return t.currentLocale.Get(key.(string), args...)
|
||||
return e.currentLocale.Get(key.(string), args...)
|
||||
case errors.LocalizedError:
|
||||
err := key.(errors.LocalizedError)
|
||||
return err.Localize(t.currentLocale)
|
||||
return err.Localize(e.currentLocale)
|
||||
case error:
|
||||
return key.(error).Error()
|
||||
default:
|
||||
|
@ -74,7 +80,7 @@ func (t *TemplateEngine) ParseAll() {
|
|||
}
|
||||
},
|
||||
"plural": func(key string, n int, args ...interface{}) string {
|
||||
return t.currentLocale.Plural(key, n, args...)
|
||||
return e.currentLocale.Plural(key, n, args...)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -85,16 +91,18 @@ func (t *TemplateEngine) ParseAll() {
|
|||
|
||||
for name, content := range templateViewsMap {
|
||||
log.Println("Parsing template:", name)
|
||||
t.templates[name] = template.Must(template.New("main").Funcs(funcMap).Parse(commonTemplates + content))
|
||||
e.templates[name] = template.Must(template.New("main").Funcs(funcMap).Parse(commonTemplates + content))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TemplateEngine) SetLanguage(language string) {
|
||||
t.currentLocale = t.translator.GetLanguage(language)
|
||||
// SetLanguage change the language for template processing.
|
||||
func (e *Engine) SetLanguage(language string) {
|
||||
e.currentLocale = e.translator.GetLanguage(language)
|
||||
}
|
||||
|
||||
func (t *TemplateEngine) Execute(w io.Writer, name string, data interface{}) {
|
||||
tpl, ok := t.templates[name]
|
||||
// Execute process a template.
|
||||
func (e *Engine) Execute(w io.Writer, name string, data interface{}) {
|
||||
tpl, ok := e.templates[name]
|
||||
if !ok {
|
||||
log.Fatalf("The template %s does not exists.\n", name)
|
||||
}
|
||||
|
@ -108,13 +116,15 @@ func (t *TemplateEngine) Execute(w io.Writer, name string, data interface{}) {
|
|||
b.WriteTo(w)
|
||||
}
|
||||
|
||||
func NewTemplateEngine(router *mux.Router, translator *locale.Translator) *TemplateEngine {
|
||||
tpl := &TemplateEngine{
|
||||
// NewEngine returns a new template Engine.
|
||||
func NewEngine(cfg *config.Config, router *mux.Router, translator *locale.Translator) *Engine {
|
||||
tpl := &Engine{
|
||||
templates: make(map[string]*template.Template),
|
||||
router: router,
|
||||
translator: translator,
|
||||
cfg: cfg,
|
||||
}
|
||||
|
||||
tpl.ParseAll()
|
||||
tpl.parseAll()
|
||||
return tpl
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.472545112 -0800 PST m=+0.018780770
|
||||
// 2017-11-21 19:31:59.633723314 -0800 PST m=+0.012722162
|
||||
|
||||
package template
|
||||
|
||||
|
@ -13,6 +13,9 @@ var templateViewsMap = map[string]string{
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
@ -267,6 +270,9 @@ var templateViewsMap = map[string]string{
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
@ -401,6 +407,9 @@ var templateViewsMap = map[string]string{
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
@ -725,6 +734,42 @@ var templateViewsMap = map[string]string{
|
|||
</div>
|
||||
</form>
|
||||
|
||||
{{ end }}
|
||||
`,
|
||||
"integrations": `{{ define "title"}}{{ t "Integrations" }}{{ end }}
|
||||
|
||||
{{ define "content"}}
|
||||
<section class="page-header">
|
||||
<h1>{{ t "Integrations" }}</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
{{ if .user.IsAdmin }}
|
||||
<li>
|
||||
<a href="{{ route "users" }}">{{ t "Users" }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
<li>
|
||||
<a href="{{ route "about" }}">{{ t "About" }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="panel">
|
||||
<h3>{{ t "Bookmarklet" }}</h3>
|
||||
<p>{{ t "This special link allows you to subscribe to a website directly by using a bookmark in your web browser." }}</p>
|
||||
|
||||
<div class="bookmarklet">
|
||||
<a href="javascript:location.href='{{ baseURL }}{{ route "bookmarklet" }}?uri='+encodeURIComponent(window.location.href)">{{ t "Add to Miniflux" }}</a>
|
||||
</div>
|
||||
|
||||
<p>{{ t "Drag and drop this link to your bookmarks." }}</p>
|
||||
</div>
|
||||
|
||||
{{ end }}
|
||||
`,
|
||||
"login": `{{ define "title"}}{{ t "Sign In" }}{{ end }}
|
||||
|
@ -760,6 +805,9 @@ var templateViewsMap = map[string]string{
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "users" }}">{{ t "Users" }}</a>
|
||||
</li>
|
||||
|
@ -806,6 +854,9 @@ var templateViewsMap = map[string]string{
|
|||
<section class="page-header">
|
||||
<h1>{{ t "Settings" }}</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
@ -920,6 +971,9 @@ var templateViewsMap = map[string]string{
|
|||
<li>
|
||||
<a href="{{ route "settings" }}">{{ t "Settings" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "integrations" }}">{{ t "Integrations" }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ route "sessions" }}">{{ t "Sessions" }}</a>
|
||||
</li>
|
||||
|
@ -972,24 +1026,25 @@ var templateViewsMap = map[string]string{
|
|||
}
|
||||
|
||||
var templateViewsMapChecksums = map[string]string{
|
||||
"about": "56f1d45d8b9944306c66be0712320527e739a0ce4fccbd97a4c414c8f9cfab04",
|
||||
"about": "ad2fb778fc73c39b733b3f81b13e5c7d689b041fadd24ee2d4577f545aa788ad",
|
||||
"add_subscription": "098ea9e492e18242bd414b22c4d8638006d113f728e5ae78c9186663f60ae3f1",
|
||||
"categories": "ca1280cd157bb527d4fc907da67b05a8347378f6dce965b9389d4bcdf3600a11",
|
||||
"category_entries": "0bdcf28ef29b976b78d1add431896a8c56791476abd7a4240998d52c3efe1f35",
|
||||
"choose_subscription": "d37682743d8bbd84738a964e238103db2651f95fa340c6e285ffe2e12548d673",
|
||||
"create_category": "2b82af5d2dcd67898dc5daa57a6461e6ff8121a6089b2a2a1be909f35e4a2275",
|
||||
"create_user": "966b31d0414e0d0a547ef9ada428cbd24a91100bfed491f780c0461892a2489b",
|
||||
"create_user": "815dd31faaa6e9ba81a2a6664e5707aaf4153c392accd2b1f77cf1937035a881",
|
||||
"edit_category": "cee720faadcec58289b707ad30af623d2ee66c1ce23a732965463250d7ff41c5",
|
||||
"edit_feed": "c5bc4c22bf7e8348d880395250545595d21fb8c8e723fc5d7cca68e25d250884",
|
||||
"edit_user": "f0f79704983de3ca7858bd8cda7a372c3999f5e4e0cf951fba5fa2c1752f9111",
|
||||
"edit_user": "c835d78f7cf36c11533db9cef253457a9003987d704070d59446cb2b0e84dcb9",
|
||||
"entry": "32e605edd6d43773ac31329d247ebd81d38d974cd43689d91de79fffec7fe04b",
|
||||
"feed_entries": "9aff923b6c7452dec1514feada7e0d2bbc1ec21c6f5e9f48b2de41d1b731ffe4",
|
||||
"feeds": "94e43404a4044490c065c888a49bebd3ff51b588b9fb47d03c2598003aa40dca",
|
||||
"history": "947603cbde888516e62925f5d08fb0b13d930623d3ee4c690dbc22612fdda75e",
|
||||
"import": "73b5112e20bfd232bf73334544186ea419505936bc237d481517a8622901878f",
|
||||
"integrations": "c485d6d9ed996635e55e73320610e6bcb01a41c1153e8e739ae2294b0b14b243",
|
||||
"login": "568f2f69f248048f3e55e9bbc719077a74ae23fe18f237aa40e3de37e97b7a41",
|
||||
"sessions": "5ac3793f0ee74d0807bab6a173a1aa6508e98add5c022fa54c8fdf5c6b4a0e75",
|
||||
"settings": "9c89bfd70ff288b4256e5205be78a7645450b364db1df51d10fee3cb915b2c6b",
|
||||
"sessions": "878dbe8f8ea783b44130c495814179519fa5c3aa2666ac87508f94d58dd008bf",
|
||||
"settings": "a972fb5767fd32522648149880e40607ed8bbed7a389038bbab6b08539ac2893",
|
||||
"unread": "b6f9be1a72188947c75a6fdcac6ff7878db7745f9efa46318e0433102892a722",
|
||||
"users": "c6b1fa81cf229dde88e69c353114b542c67794a2cd513eddaf600828ab14aa18",
|
||||
"users": "44677e28bb5347799ed0020c90ec785aadec4b1454446d92411cfdaf6e32110b",
|
||||
}
|
||||
|
|
20
server/ui/controller/integrations.go
Normal file
20
server/ui/controller/integrations.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2017 Frédéric Guillot. All rights reserved.
|
||||
// Use of this source code is governed by the Apache 2.0
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package controller
|
||||
|
||||
import "github.com/miniflux/miniflux2/server/core"
|
||||
|
||||
// ShowIntegrations renders the page with all external integrations.
|
||||
func (c *Controller) ShowIntegrations(ctx *core.Context, request *core.Request, response *core.Response) {
|
||||
args, err := c.getCommonTemplateArgs(ctx)
|
||||
if err != nil {
|
||||
response.HTML().ServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
response.HTML().Render("integrations", args.Merge(tplParams{
|
||||
"menu": "settings",
|
||||
}))
|
||||
}
|
|
@ -5,13 +5,30 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/miniflux/miniflux2/model"
|
||||
"github.com/miniflux/miniflux2/reader/subscription"
|
||||
"github.com/miniflux/miniflux2/server/core"
|
||||
"github.com/miniflux/miniflux2/server/ui/form"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Bookmarklet prefill the form to add a subscription from the URL provided by the bookmarklet.
|
||||
func (c *Controller) Bookmarklet(ctx *core.Context, request *core.Request, response *core.Response) {
|
||||
user := ctx.LoggedUser()
|
||||
args, err := c.getSubscriptionFormTemplateArgs(ctx, user)
|
||||
if err != nil {
|
||||
response.HTML().ServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
bookmarkletURL := request.QueryStringParam("uri", "")
|
||||
response.HTML().Render("add_subscription", args.Merge(tplParams{
|
||||
"form": &form.SubscriptionForm{URL: bookmarkletURL},
|
||||
}))
|
||||
}
|
||||
|
||||
// AddSubscription shows the form to add a new feed.
|
||||
func (c *Controller) AddSubscription(ctx *core.Context, request *core.Request, response *core.Response) {
|
||||
user := ctx.LoggedUser()
|
||||
|
||||
|
@ -24,6 +41,7 @@ func (c *Controller) AddSubscription(ctx *core.Context, request *core.Request, r
|
|||
response.HTML().Render("add_subscription", args)
|
||||
}
|
||||
|
||||
// SubmitSubscription try to find a feed from the URL provided by the user.
|
||||
func (c *Controller) SubmitSubscription(ctx *core.Context, request *core.Request, response *core.Response) {
|
||||
user := ctx.LoggedUser()
|
||||
|
||||
|
@ -80,6 +98,7 @@ func (c *Controller) SubmitSubscription(ctx *core.Context, request *core.Request
|
|||
}
|
||||
}
|
||||
|
||||
// ChooseSubscription shows a page to choose a subscription.
|
||||
func (c *Controller) ChooseSubscription(ctx *core.Context, request *core.Request, response *core.Response) {
|
||||
user := ctx.LoggedUser()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2017-11-21 15:41:59.457985225 -0800 PST m=+0.004220883
|
||||
// 2017-11-21 19:31:59.625242989 -0800 PST m=+0.004241837
|
||||
|
||||
package sql
|
||||
|
||||
|
|
Loading…
Reference in a new issue