diff --git a/Makefile b/Makefile index 2084cc41..feb94df5 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ DEB_IMG_ARCH := amd64 export PGPASSWORD := postgres -.PHONY: generate \ +.PHONY: \ miniflux \ linux-amd64 \ linux-arm64 \ @@ -41,64 +41,61 @@ export PGPASSWORD := postgres debian \ debian-packages -generate: - @ go generate - -miniflux: generate +miniflux: @ go build -ldflags=$(LD_FLAGS) -o $(APP) main.go -linux-amd64: generate +linux-amd64: @ GOOS=linux GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-amd64 main.go -linux-arm64: generate +linux-arm64: @ GOOS=linux GOARCH=arm64 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-arm64 main.go -linux-armv7: generate +linux-armv7: @ GOOS=linux GOARCH=arm GOARM=7 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-armv7 main.go -linux-armv6: generate +linux-armv6: @ GOOS=linux GOARCH=arm GOARM=6 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-armv6 main.go -linux-armv5: generate +linux-armv5: @ GOOS=linux GOARCH=arm GOARM=5 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-armv5 main.go -darwin-amd64: generate +darwin-amd64: @ GOOS=darwin GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-darwin-amd64 main.go -darwin-arm64: generate +darwin-arm64: @ GOOS=darwin GOARCH=arm64 go build -ldflags=$(LD_FLAGS) -o $(APP)-darwin-arm64 main.go -freebsd-amd64: generate +freebsd-amd64: @ GOOS=freebsd GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-freebsd-amd64 main.go -openbsd-amd64: generate +openbsd-amd64: @ GOOS=openbsd GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-openbsd-amd64 main.go -windows-amd64: generate +windows-amd64: @ GOOS=windows GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-windows-amd64 main.go build: linux-amd64 linux-arm64 linux-armv7 linux-armv6 linux-armv5 darwin-amd64 darwin-arm64 freebsd-amd64 openbsd-amd64 windows-amd64 # NOTE: unsupported targets -netbsd-amd64: generate +netbsd-amd64: @ GOOS=netbsd GOARCH=amd64 go build -ldflags=$(LD_FLAGS) -o $(APP)-netbsd-amd64 main.go -linux-x86: generate +linux-x86: @ GOOS=linux GOARCH=386 go build -ldflags=$(LD_FLAGS) -o $(APP)-linux-x86 main.go -freebsd-x86: generate +freebsd-x86: @ GOOS=freebsd GOARCH=386 go build -ldflags=$(LD_FLAGS) -o $(APP)-freebsd-x86 main.go -netbsd-x86: generate +netbsd-x86: @ GOOS=netbsd GOARCH=386 go build -ldflags=$(LD_FLAGS) -o $(APP)-netbsd-x86 main.go -openbsd-x86: generate +openbsd-x86: @ GOOS=openbsd GOARCH=386 go build -ldflags=$(LD_FLAGS) -o $(APP)-freebsd-x86 main.go -windows-x86: generate +windows-x86: @ GOOS=windows GOARCH=386 go build -ldflags=$(LD_FLAGS) -o $(APP)-windows-x86 main.go -run: generate +run: @ LOG_DATE_TIME=1 go run main.go -debug clean: diff --git a/generate.go b/generate.go deleted file mode 100644 index 9edc992d..00000000 --- a/generate.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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. - -// +build ignore - -package main - -import ( - "crypto/sha256" - "fmt" - "os" - "path" - "path/filepath" - "strings" - "text/template" -) - -const tpl = `// Code generated by go generate; DO NOT EDIT. - -package {{ .Package }} // import "miniflux.app/{{ .ImportPath }}" - -var {{ .Map }} = map[string]string{ -{{ range $constant, $content := .Files }}` + "\t" + `"{{ $constant }}": ` + "`{{ $content }}`" + `, -{{ end }}} - -var {{ .Map }}Checksums = map[string]string{ -{{ range $constant, $content := .Checksums }}` + "\t" + `"{{ $constant }}": "{{ $content }}", -{{ end }}} -` - -var bundleTpl = template.Must(template.New("").Parse(tpl)) - -type Bundle struct { - Package string - Map string - ImportPath string - Files map[string]string - Checksums map[string]string -} - -func (b *Bundle) Write(filename string) { - f, err := os.Create(filename) - if err != nil { - panic(err) - } - defer f.Close() - - bundleTpl.Execute(f, b) -} - -func NewBundle(pkg, mapName, importPath string) *Bundle { - return &Bundle{ - Package: pkg, - Map: mapName, - ImportPath: importPath, - Files: make(map[string]string), - Checksums: make(map[string]string), - } -} - -func readFile(filename string) []byte { - data, err := os.ReadFile(filename) - if err != nil { - panic(err) - } - return data -} - -func checksum(data []byte) string { - return fmt.Sprintf("%x", sha256.Sum256(data)) -} - -func basename(filename string) string { - return path.Base(filename) -} - -func stripExtension(filename string) string { - filename = strings.TrimSuffix(filename, path.Ext(filename)) - return strings.Replace(filename, " ", "_", -1) -} - -func glob(pattern string) []string { - // There is no Glob function in path package, so we have to use filepath and replace in case of Windows - files, _ := filepath.Glob(pattern) - for i := range files { - if strings.Contains(files[i], "\\") { - files[i] = strings.Replace(files[i], "\\", "/", -1) - } - } - return files -} - -func generateBundle(bundleFile, pkg, mapName string, srcFiles []string) { - bundle := NewBundle(pkg, mapName, pkg) - - for _, srcFile := range srcFiles { - data := readFile(srcFile) - filename := stripExtension(basename(srcFile)) - - bundle.Files[filename] = string(data) - bundle.Checksums[filename] = checksum(data) - } - - bundle.Write(bundleFile) -} - -func main() { - generateBundle("template/views.go", "template", "templateViewsMap", glob("template/html/*.html")) - generateBundle("template/common.go", "template", "templateCommonMap", glob("template/html/common/*.html")) -} diff --git a/main.go b/main.go index 668827d6..aaed0c53 100644 --- a/main.go +++ b/main.go @@ -4,10 +4,6 @@ package main // import "miniflux.app" -//go:generate go run generate.go -//go:generate gofmt -s -w template/views.go -//go:generate gofmt -s -w template/common.go - import ( "miniflux.app/cli" ) diff --git a/template/common.go b/template/common.go deleted file mode 100644 index 1a85700f..00000000 --- a/template/common.go +++ /dev/null @@ -1,548 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. - -package template // import "miniflux.app/template" - -var templateCommonMap = map[string]string{ - "entry_pagination": `{{ define "entry_pagination" }} - -{{ end }} -`, - "feed_list": `{{ define "feed_list" }} -
- {{ range .feeds }} -
-
- - {{ if .Icon }} - {{ .Title }} - {{ end }} - {{ if .Disabled }} 🚫 {{ end }} - {{ .Title }} - - - ({{ .UnreadCount }}/{{ .ReadCount }}) - - - {{ .Category.Title }} - -
-
-
    -
  • - {{ domain .SiteURL }} -
  • -
  • - {{ t "page.feeds.last_check" }} -
  • -
- -
- {{ if ne .ParsingErrorCount 0 }} -
- {{ plural "page.feeds.error_count" .ParsingErrorCount .ParsingErrorCount }} - - {{ .ParsingErrorMsg }} -
- {{ end }} -
- {{ end }} -
-{{ end }} -`, - "feed_menu": `{{ define "feed_menu" }} - -{{ end }}`, - "icons": ` -{{ define "icon_read" }} - - - - - -{{ end }} -{{ define "icon_unread" }} - - - - - -{{ end }} -{{ define "icon_star" }} - - - - -{{ end }} -{{ define "icon_unstar" }} - - - - -{{ end }} -{{ define "icon_save" }} - - - - - - -{{ end }} -{{ define "icon_scraper" }} - - - - - - -{{ end }} -{{ define "icon_share" }} - - - - - - - - -{{ end }} -{{ define "icon_comment" }} - - - - - - - -{{ end }} -{{ define "icon_external_link" }} - - - - - - -{{ end }} -{{ define "icon_delete" }} - - - - - - - - -{{ end }} -{{ define "icon_edit" }} - - - - - - -{{ end }} -{{ define "icon_feeds" }} - - - - - -{{ end }} -{{ define "icon_entries" }} - - - - - - - -{{ end }} -{{ define "icon_refresh" }} - - - - - -{{ end }}`, - "item_meta": `{{ define "item_meta" }} -
- - -
-{{ end }} -`, - "layout": `{{ define "base" }} - - - - - {{template "title" .}} - Miniflux - - - - - - - - - - - - - - - - - - - - - - - - - - {{ if .csrf }} - - {{ end }} - - - - {{ if and .user .user.Stylesheet }} - - {{ end }} - - - - - -
- -
- {{ if .user }} -
- -
- {{ end }} - {{ if .flashMessage }} -
{{ .flashMessage }}
- {{ end }} - {{ if .flashErrorMessage }} -
{{ .flashErrorMessage }}
- {{ end }} -
- {{template "content" .}} -
- - - - - - - -{{ end }} -`, - "pagination": `{{ define "pagination" }} - -{{ end }} -`, - "settings_menu": `{{ define "settings_menu" }} - -{{ end }}`, -} - -var templateCommonMapChecksums = map[string]string{ - "entry_pagination": "cdca9cf12586e41e5355190b06d9168f57f77b85924d1e63b13524bc15abcbf6", - "feed_list": "931e43d328a116318c510de5658c688cd940b934c86b6ec82a472e1f81e020ae", - "feed_menu": "318d8662dda5ca9dfc75b909c8461e79c86fb5082df1428f67aaf856f19f4b50", - "icons": "7161afa4cce46245a99cb1e49a605d3ff30e907c3f568ef9c17218718d20e042", - "item_meta": "fefa219c8296f0370632336ed59a2c8b0c2146ee77f3b10de1d9b87982219dc5", - "layout": "03c77ed0163b790c0622ecec173119537087c66f6a3925a931ae83a9a94d32cf", - "pagination": "7b61288e86283c4cf0dc83bcbf8bf1c00c7cb29e60201c8c0b633b2450d2911f", - "settings_menu": "e2b777630c0efdbc529800303c01d6744ed3af80ec505ac5a5b3f99c9b989156", -} diff --git a/template/doc.go b/template/doc.go deleted file mode 100644 index a4da6b2a..00000000 --- a/template/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018 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 template handles template parsing and execution. - -*/ -package template // import "miniflux.app/template" diff --git a/template/engine.go b/template/engine.go index c7f75660..5f4d71e2 100644 --- a/template/engine.go +++ b/template/engine.go @@ -6,7 +6,9 @@ package template // import "miniflux.app/template" import ( "bytes" + "embed" "html/template" + "strings" "time" "miniflux.app/errors" @@ -16,22 +18,64 @@ import ( "github.com/gorilla/mux" ) +//go:embed templates/common/*.html +var commonTemplateFiles embed.FS + +//go:embed templates/views/*.html +var viewTemplateFiles embed.FS + // Engine handles the templating system. type Engine struct { templates map[string]*template.Template funcMap *funcMap } -func (e *Engine) parseAll() { - commonTemplates := "" - for _, content := range templateCommonMap { - commonTemplates += content +// NewEngine returns a new template engine. +func NewEngine(router *mux.Router) *Engine { + return &Engine{ + templates: make(map[string]*template.Template), + funcMap: &funcMap{router}, + } +} + +// ParseTemplates parses template files embed into the application. +func (e *Engine) ParseTemplates() error { + var commonTemplateContents strings.Builder + + dirEntries, err := commonTemplateFiles.ReadDir("templates/common") + if err != nil { + return err } - for name, content := range templateViewsMap { - logger.Debug("[Template] Parsing: %s", name) - e.templates[name] = template.Must(template.New("main").Funcs(e.funcMap.Map()).Parse(commonTemplates + content)) + for _, dirEntry := range dirEntries { + fileData, err := commonTemplateFiles.ReadFile("templates/common/" + dirEntry.Name()) + if err != nil { + return err + } + commonTemplateContents.Write(fileData) } + + dirEntries, err = viewTemplateFiles.ReadDir("templates/views") + if err != nil { + return err + } + + for _, dirEntry := range dirEntries { + templateName := dirEntry.Name() + fileData, err := viewTemplateFiles.ReadFile("templates/views/" + dirEntry.Name()) + if err != nil { + return err + } + + var templateContents strings.Builder + templateContents.WriteString(commonTemplateContents.String()) + templateContents.Write(fileData) + + logger.Debug("[Template] Parsing: %s", templateName) + e.templates[templateName] = template.Must(template.New("main").Funcs(e.funcMap.Map()).Parse(templateContents.String())) + } + + return nil } // Render process a template. @@ -75,14 +119,3 @@ func (e *Engine) Render(name, language string, data interface{}) []byte { return b.Bytes() } - -// NewEngine returns a new template engine. -func NewEngine(router *mux.Router) *Engine { - tpl := &Engine{ - templates: make(map[string]*template.Template), - funcMap: &funcMap{router}, - } - - tpl.parseAll() - return tpl -} diff --git a/template/html/common/entry_pagination.html b/template/templates/common/entry_pagination.html similarity index 100% rename from template/html/common/entry_pagination.html rename to template/templates/common/entry_pagination.html diff --git a/template/html/common/feed_list.html b/template/templates/common/feed_list.html similarity index 100% rename from template/html/common/feed_list.html rename to template/templates/common/feed_list.html diff --git a/template/html/common/feed_menu.html b/template/templates/common/feed_menu.html similarity index 100% rename from template/html/common/feed_menu.html rename to template/templates/common/feed_menu.html diff --git a/template/html/common/icons.html b/template/templates/common/icons.html similarity index 100% rename from template/html/common/icons.html rename to template/templates/common/icons.html diff --git a/template/html/common/item_meta.html b/template/templates/common/item_meta.html similarity index 100% rename from template/html/common/item_meta.html rename to template/templates/common/item_meta.html diff --git a/template/html/common/layout.html b/template/templates/common/layout.html similarity index 100% rename from template/html/common/layout.html rename to template/templates/common/layout.html diff --git a/template/html/common/pagination.html b/template/templates/common/pagination.html similarity index 100% rename from template/html/common/pagination.html rename to template/templates/common/pagination.html diff --git a/template/html/common/settings_menu.html b/template/templates/common/settings_menu.html similarity index 100% rename from template/html/common/settings_menu.html rename to template/templates/common/settings_menu.html diff --git a/template/html/about.html b/template/templates/views/about.html similarity index 100% rename from template/html/about.html rename to template/templates/views/about.html diff --git a/template/html/add_subscription.html b/template/templates/views/add_subscription.html similarity index 100% rename from template/html/add_subscription.html rename to template/templates/views/add_subscription.html diff --git a/template/html/api_keys.html b/template/templates/views/api_keys.html similarity index 100% rename from template/html/api_keys.html rename to template/templates/views/api_keys.html diff --git a/template/html/bookmark_entries.html b/template/templates/views/bookmark_entries.html similarity index 100% rename from template/html/bookmark_entries.html rename to template/templates/views/bookmark_entries.html diff --git a/template/html/categories.html b/template/templates/views/categories.html similarity index 100% rename from template/html/categories.html rename to template/templates/views/categories.html diff --git a/template/html/category_entries.html b/template/templates/views/category_entries.html similarity index 100% rename from template/html/category_entries.html rename to template/templates/views/category_entries.html diff --git a/template/html/category_feeds.html b/template/templates/views/category_feeds.html similarity index 100% rename from template/html/category_feeds.html rename to template/templates/views/category_feeds.html diff --git a/template/html/choose_subscription.html b/template/templates/views/choose_subscription.html similarity index 100% rename from template/html/choose_subscription.html rename to template/templates/views/choose_subscription.html diff --git a/template/html/create_api_key.html b/template/templates/views/create_api_key.html similarity index 100% rename from template/html/create_api_key.html rename to template/templates/views/create_api_key.html diff --git a/template/html/create_category.html b/template/templates/views/create_category.html similarity index 100% rename from template/html/create_category.html rename to template/templates/views/create_category.html diff --git a/template/html/create_user.html b/template/templates/views/create_user.html similarity index 100% rename from template/html/create_user.html rename to template/templates/views/create_user.html diff --git a/template/html/edit_category.html b/template/templates/views/edit_category.html similarity index 100% rename from template/html/edit_category.html rename to template/templates/views/edit_category.html diff --git a/template/html/edit_feed.html b/template/templates/views/edit_feed.html similarity index 100% rename from template/html/edit_feed.html rename to template/templates/views/edit_feed.html diff --git a/template/html/edit_user.html b/template/templates/views/edit_user.html similarity index 100% rename from template/html/edit_user.html rename to template/templates/views/edit_user.html diff --git a/template/html/entry.html b/template/templates/views/entry.html similarity index 100% rename from template/html/entry.html rename to template/templates/views/entry.html diff --git a/template/html/feed_entries.html b/template/templates/views/feed_entries.html similarity index 100% rename from template/html/feed_entries.html rename to template/templates/views/feed_entries.html diff --git a/template/html/feeds.html b/template/templates/views/feeds.html similarity index 100% rename from template/html/feeds.html rename to template/templates/views/feeds.html diff --git a/template/html/history_entries.html b/template/templates/views/history_entries.html similarity index 100% rename from template/html/history_entries.html rename to template/templates/views/history_entries.html diff --git a/template/html/import.html b/template/templates/views/import.html similarity index 100% rename from template/html/import.html rename to template/templates/views/import.html diff --git a/template/html/integrations.html b/template/templates/views/integrations.html similarity index 100% rename from template/html/integrations.html rename to template/templates/views/integrations.html diff --git a/template/html/login.html b/template/templates/views/login.html similarity index 100% rename from template/html/login.html rename to template/templates/views/login.html diff --git a/template/html/search_entries.html b/template/templates/views/search_entries.html similarity index 100% rename from template/html/search_entries.html rename to template/templates/views/search_entries.html diff --git a/template/html/sessions.html b/template/templates/views/sessions.html similarity index 100% rename from template/html/sessions.html rename to template/templates/views/sessions.html diff --git a/template/html/settings.html b/template/templates/views/settings.html similarity index 100% rename from template/html/settings.html rename to template/templates/views/settings.html diff --git a/template/html/shared_entries.html b/template/templates/views/shared_entries.html similarity index 100% rename from template/html/shared_entries.html rename to template/templates/views/shared_entries.html diff --git a/template/html/unread_entries.html b/template/templates/views/unread_entries.html similarity index 100% rename from template/html/unread_entries.html rename to template/templates/views/unread_entries.html diff --git a/template/html/users.html b/template/templates/views/users.html similarity index 100% rename from template/html/users.html rename to template/templates/views/users.html diff --git a/template/views.go b/template/views.go deleted file mode 100644 index 56c9284f..00000000 --- a/template/views.go +++ /dev/null @@ -1,1643 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. - -package template // import "miniflux.app/template" - -var templateViewsMap = map[string]string{ - "about": `{{ define "title"}}{{ t "page.about.title" }}{{ end }} - -{{ define "content"}} - - -
-

Miniflux

- -
- -
-

{{ t "page.about.credits" }}

- -
- -{{ if .user.IsAdmin }} -
-

{{ t "page.about.global_config_options" }}

- -
-{{ end }} - -{{ end }} -`, - "add_subscription": `{{ define "title"}}{{ t "page.add_feed.title" }}{{ end }} - -{{ define "content"}} - - -{{ if not .categories }} -

{{ t "page.add_feed.no_category" }}

-{{ else }} -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - - - - -
- {{ t "page.add_feed.legend.advanced_options" }} -
- - {{ if .hasProxyConfigured }} - - {{ end }} - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
-
-{{ end }} - -{{ end }} -`, - "api_keys": `{{ define "title"}}{{ t "page.api_keys.title" }}{{ end }} - -{{ define "content"}} - - -{{ if .apiKeys }} -{{ range .apiKeys }} - - - - - - - - - - - - - - - - - - - - - -
{{ t "page.api_keys.table.description" }}{{ .Description }}
{{ t "page.api_keys.table.token" }}{{ .Token }}
{{ t "page.api_keys.table.last_used_at" }} - {{ if .LastUsedAt }} - - {{ else }} - {{ t "page.api_keys.never_used" }} - {{ end }} -
{{ t "page.api_keys.table.created_at" }} - -
{{ t "page.api_keys.table.actions" }} - {{ t "action.remove" }} -
-
-{{ end }} -{{ end }} - -

{{ t "page.integration.miniflux_api" }}

-
- -
- -

- {{ t "menu.create_api_key" }} -

- -{{ end }} -`, - "bookmark_entries": `{{ define "title"}}{{ t "page.starred.title" }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .entries }} -

{{ t "alert.no_bookmark" }}

-{{ else }} -
- {{ range .entries }} -
-
- - {{ if ne .Feed.Icon.IconID 0 }} - {{ .Feed.Title }} - {{ end }} - {{ .Title }} - - {{ .Feed.Category.Title }} -
- {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} -
- {{ end }} -
- {{ template "pagination" .pagination }} -{{ end }} - -{{ end }} -`, - "categories": `{{ define "title"}}{{ t "page.categories.title" }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .categories }} -

{{ t "alert.no_category" }}

-{{ else }} -
- {{ range .categories }} -
-
- - {{ .Title }} - - ({{ .FeedCount }}) -
-
-
    -
  • - {{ if eq .FeedCount 0 }}{{ t "page.categories.no_feed" }}{{ else }}{{ plural "page.categories.feed_count" .FeedCount .FeedCount }}{{ end }} -
  • -
- -
-
- {{ end }} -
-{{ end }} - -{{ end }} -`, - "category_entries": `{{ define "title"}}{{ .category.Title }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .entries }} -

{{ t "alert.no_category_entry" }}

-{{ else }} -
- {{ range .entries }} -
-
- - {{ if ne .Feed.Icon.IconID 0 }} - {{ .Feed.Title }} - {{ end }} - {{ .Title }} - - {{ .Feed.Category.Title }} -
- {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} -
- {{ end }} -
- - {{ template "pagination" .pagination }} -{{ end }} - -{{ end }} -`, - "category_feeds": `{{ define "title"}}{{ .category.Title }} > {{ t "page.feeds.title" }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .feeds }} -

{{ t "alert.no_feed_in_category" }}

-{{ else }} - {{ template "feed_list" dict "user" .user "feeds" .feeds "ParsingErrorCount" .ParsingErrorCount }} -{{ end }} - -{{ end }} -`, - "choose_subscription": `{{ define "title"}}{{ t "page.add_feed.title" }}{{ end }} - -{{ define "content"}} - - -
- - - - - - - - {{ if .form.FetchViaProxy }} - - {{ end }} - {{ if .form.Crawler }} - - {{ end }} - -

{{ t "page.add_feed.choose_feed" }}

- - {{ range .subscriptions }} -
- ({{ .Type }}) - {{ .URL | safeURL }} -
- {{ end }} - -
- -
-
-{{ end }} -`, - "create_api_key": `{{ define "title"}}{{ t "page.new_api_key.title" }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - -
- {{ t "action.or" }} {{ t "action.cancel" }} -
-
-{{ end }} -`, - "create_category": `{{ define "title"}}{{ t "page.new_category.title" }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - -
- {{ t "action.or" }} {{ t "action.cancel" }} -
-
-{{ end }} -`, - "create_user": `{{ define "title"}}{{ t "page.new_user.title" }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - - - - - - - - - -
- {{ t "action.or" }} {{ t "action.cancel" }} -
-
-{{ end }} -`, - "edit_category": `{{ define "title"}}{{ t "page.edit_category.title" .category.Title }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - -
- -
-
-{{ end }} -`, - "edit_feed": `{{ define "title"}}{{ t "page.edit_feed.title" .feed.Title }}{{ end }} - -{{ define "content"}} - - -{{ if not .categories }} -

{{ t "page.add_feed.no_category" }}

-{{ else }} - {{ if ne .feed.ParsingErrorCount 0 }} -
-

{{ t "page.edit_feed.last_parsing_error" }}

-

{{ t .feed.ParsingErrorMsg }}

-
- {{ end }} - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ if .hasProxyConfigured }} - - {{ end }} - - -
- {{ t "action.or" }} {{ t "action.cancel" }} -
-
- -
- -
- -
- {{ t "action.remove_feed" }} -
-{{ end }} - -{{ end }} -`, - "edit_user": `{{ define "title"}}{{ t "page.edit_user.title" .selected_user.Username }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - - - - - - - - - - - - -
- {{ t "action.or" }} {{ t "action.cancel" }} -
-
-{{ end }} -`, - "entry": `{{ define "title"}}{{ .entry.Title }}{{ end }} - -{{ define "content"}} -
-
-

- {{ .entry.Title }} -

- {{ if .user }} -
- -
- {{ end }} - - -
- {{ if gt (len .entry.Content) 120 }} - {{ if .user }} -
- {{ template "entry_pagination" . }} -
- {{ end }} - {{ end }} -
- {{ if .user }} - {{ noescape (proxyFilter .entry.Content) }} - {{ else }} - {{ noescape .entry.Content }} - {{ end }} -
- {{ if .entry.Enclosures }} -
- {{ t "page.entry.attachments" }} ({{ len .entry.Enclosures }}) - {{ range .entry.Enclosures }} - {{ if ne .URL "" }} -
- {{ if hasPrefix .MimeType "audio/" }} -
- -
- {{ else if hasPrefix .MimeType "video/" }} -
- -
- {{ else if hasPrefix .MimeType "image/" }} -
- {{ if $.user }} - {{ .URL }} ({{ .MimeType }}) - {{ else }} - {{ .URL }} ({{ .MimeType }}) - {{ end }} -
- {{ end }} - -
- {{ .URL | safeURL }} - {{ if gt .Size 0 }} - {{ formatFileSize .Size }}{{ end }} -
-
- {{ end }} - {{ end }} -
- {{ end }} -
- -{{ if .user }} -
- {{ template "entry_pagination" . }} -
-{{ end }} -{{ end }} -`, - "feed_entries": `{{ define "title"}}{{ .feed.Title }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if ne .feed.ParsingErrorCount 0 }} -
-

{{ t "alert.feed_error" }}

-

{{ t .feed.ParsingErrorMsg }}

-
-{{ end }} - -{{ if not .entries }} - {{ if .showOnlyUnreadEntries }} -

{{ t "alert.no_unread_entry" }}

- {{ else }} -

{{ t "alert.no_feed_entry" }}

- {{ end }} -{{ else }} -
- {{ range .entries }} -
-
- - {{ if ne .Feed.Icon.IconID 0 }} - {{ .Feed.Title }} - {{ end }} - {{ .Title }} - - {{ .Feed.Category.Title }} -
- {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} -
- {{ end }} -
- - {{ template "pagination" .pagination }} -{{ end }} - -{{ end }} -`, - "feeds": `{{ define "title"}}{{ t "page.feeds.title" }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .feeds }} -

{{ t "alert.no_feed" }}

-{{ else }} - {{ template "feed_list" dict "user" .user "feeds" .feeds "ParsingErrorCount" .ParsingErrorCount }} -{{ end }} - -{{ end }} -`, - "history_entries": `{{ define "title"}}{{ t "page.history.title" }} ({{ .total }}){{ end }} - -{{ define "content"}} - - -{{ if not .entries }} -

{{ t "alert.no_history" }}

-{{ else }} -
- {{ range .entries }} -
-
- - {{ if ne .Feed.Icon.IconID 0 }} - {{ .Feed.Title }} - {{ end }} - {{ .Title }} - - {{ .Feed.Category.Title }} -
- {{ template "item_meta" dict "user" $.user "entry" . "hasSaveEntry" $.hasSaveEntry }} -
- {{ end }} -
- {{ template "pagination" .pagination }} -{{ end }} - -{{ end }} -`, - "import": `{{ define "title"}}{{ t "page.import.title" }}{{ end }} - -{{ define "content"}} - - -{{ if .errorMessage }} -
{{ t .errorMessage }}
-{{ end }} - -
- - - - - -
- -
-
-
-
- - - - - -
- -
-
- -{{ end }} -`, - "integrations": `{{ define "title"}}{{ t "page.integrations.title" }}{{ end }} - -{{ define "content"}} - - -
- - - {{ if .errorMessage }} -
{{ t .errorMessage }}
- {{ end }} - -

Fever

-
- - - - - - - - -

{{ t "form.integration.fever_endpoint" }} {{ rootURL }}{{ route "feverEndpoint" }}

- -
- -
-
- -

Pinboard

-
- - - - - - - - - - -
- -
-
- -

Instapaper

-
- - - - - - - - -
- -
-
- -

Pocket

-
- - - {{ if not .hasPocketConsumerKeyConfigured }} - - - {{ end }} - - - - - {{ if not .form.PocketAccessToken }} -

{{ t "form.integration.pocket_connect_link" }}

- {{ end }} - -
- -
-
- -

Wallabag

-
- - - - - - - - - - - - - - - - - -
- -
-
- -

Nunux Keeper

-
- - - - - - - - -
- -
-
- -
- -

{{ t "page.integration.bookmarklet" }}

-
-

{{ t "page.integration.bookmarklet.help" }}

- -
-