mirror of
				https://github.com/filebrowser/filebrowser.git
				synced 2025-11-04 03:12:57 +00:00 
			
		
		
		
	updates, sort interface
This commit is contained in:
		
							parent
							
								
									d847909da8
								
							
						
					
					
						commit
						abb9c4efe1
					
				@ -38,6 +38,7 @@ module.exports = function(grunt) {
 | 
			
		||||
        src: ['node_modules/normalize.css/normalize.css',
 | 
			
		||||
          'node_modules/font-awesome/css/font-awesome.css',
 | 
			
		||||
          'node_modules/animate.css/animate.min.css',
 | 
			
		||||
          'node_modules/codemirror/lib/codemirror.css',
 | 
			
		||||
          'assets/css/src/main.css'
 | 
			
		||||
        ],
 | 
			
		||||
        dest: 'assets/css/src/main.css',
 | 
			
		||||
@ -73,6 +74,7 @@ module.exports = function(grunt) {
 | 
			
		||||
            'node_modules/noty/js/noty/packaged/jquery.noty.packaged.min.js',
 | 
			
		||||
            'node_modules/jquery-pjax/jquery.pjax.js',
 | 
			
		||||
            'node_modules/jquery-serializejson/jquery.serializejson.min.js',
 | 
			
		||||
            'node_modules/codemirror/lib/codemirror.js',
 | 
			
		||||
            'assets/js/src/**/*.js'
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								assets/css/main.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								assets/css/main.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										7
									
								
								assets/js/app.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								assets/js/app.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -41,6 +41,7 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
			
		||||
				Template:  tpl,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		IgnoreIndexes: true,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return b.ServeHTTP(w, r)
 | 
			
		||||
 | 
			
		||||
@ -91,7 +91,8 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		page := new(page.Page)
 | 
			
		||||
		page.Name = "Edit"
 | 
			
		||||
		page.Name = "Editor"
 | 
			
		||||
		page.Class = "editor"
 | 
			
		||||
		page.Body = inf
 | 
			
		||||
		return page.Render(w, r, "edit", "frontmatter")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/hacdias/caddy-hugo/utils"
 | 
			
		||||
	"github.com/spf13/hugo/parser"
 | 
			
		||||
@ -64,9 +65,9 @@ func rawToPretty(config interface{}, parent *frontmatter) interface{} {
 | 
			
		||||
		log.Panic("Parent type not allowed.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sortByTitle(objects)
 | 
			
		||||
	sortByTitle(arrays)
 | 
			
		||||
	sortByTitle(fields)
 | 
			
		||||
	sort.Sort(sortByTitle(objects))
 | 
			
		||||
	sort.Sort(sortByTitle(arrays))
 | 
			
		||||
	sort.Sort(sortByTitle(fields))
 | 
			
		||||
 | 
			
		||||
	settings := []*frontmatter{}
 | 
			
		||||
	settings = append(settings, fields...)
 | 
			
		||||
@ -75,26 +76,12 @@ func rawToPretty(config interface{}, parent *frontmatter) interface{} {
 | 
			
		||||
	return settings
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sortByTitle(config []*frontmatter) {
 | 
			
		||||
	keys := make([]string, len(config))
 | 
			
		||||
	positionByTitle := make(map[string]int)
 | 
			
		||||
type sortByTitle []*frontmatter
 | 
			
		||||
 | 
			
		||||
	for index, element := range config {
 | 
			
		||||
		keys[index] = element.Title
 | 
			
		||||
		positionByTitle[element.Title] = index
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Strings(keys)
 | 
			
		||||
	// TODO: http://golang.org/pkg/sort/#Interface
 | 
			
		||||
	cnf := make([]*frontmatter, len(config))
 | 
			
		||||
 | 
			
		||||
	for index, title := range keys {
 | 
			
		||||
		cnf[index] = config[positionByTitle[title]]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for index := range config {
 | 
			
		||||
		config[index] = cnf[index]
 | 
			
		||||
	}
 | 
			
		||||
func (f sortByTitle) Len() int      { return len(f) }
 | 
			
		||||
func (f sortByTitle) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
 | 
			
		||||
func (f sortByTitle) Less(i, j int) bool {
 | 
			
		||||
	return strings.ToLower(f[i].Name) < strings.ToLower(f[j].Name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleObjects(content interface{}, parent *frontmatter, name string) *frontmatter {
 | 
			
		||||
@ -133,6 +120,7 @@ func handleFlatValues(content interface{}, parent *frontmatter, name string) *fr
 | 
			
		||||
	c := new(frontmatter)
 | 
			
		||||
	c.Parent = parent
 | 
			
		||||
 | 
			
		||||
	// TODO: see why isn't this working
 | 
			
		||||
	switch reflect.ValueOf(content).Kind() {
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		c.Type = "boolean"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										53
									
								
								hugo.go
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								hugo.go
									
									
									
									
									
								
							@ -18,7 +18,6 @@ import (
 | 
			
		||||
	"github.com/spf13/hugo/commands"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Setup function
 | 
			
		||||
func Setup(c *setup.Controller) (middleware.Middleware, error) {
 | 
			
		||||
	commands.Execute()
 | 
			
		||||
 | 
			
		||||
@ -30,11 +29,22 @@ func Setup(c *setup.Controller) (middleware.Middleware, error) {
 | 
			
		||||
type handler struct{ Next middleware.Handler }
 | 
			
		||||
 | 
			
		||||
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
			
		||||
	// Only handle /admin path
 | 
			
		||||
	if middleware.Path(r.URL.Path).Matches("/admin") {
 | 
			
		||||
		page := utils.ParseComponents(r)[1]
 | 
			
		||||
		code := 404
 | 
			
		||||
		var err error
 | 
			
		||||
		var page string
 | 
			
		||||
		code := 404
 | 
			
		||||
 | 
			
		||||
		// If the length of the components string is less than one, the variable
 | 
			
		||||
		// page will always be "admin"
 | 
			
		||||
		if len(utils.ParseComponents(r)) > 1 {
 | 
			
		||||
			page = utils.ParseComponents(r)[1]
 | 
			
		||||
		} else {
 | 
			
		||||
			page = utils.ParseComponents(r)[0]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the page isn't "assets" neither "edit", it should always put a
 | 
			
		||||
		// trailing slash in the path
 | 
			
		||||
		if page != "assets" && page != "edit" {
 | 
			
		||||
			if r.URL.Path[len(r.URL.Path)-1] != '/' {
 | 
			
		||||
				http.Redirect(w, r, r.URL.Path+"/", http.StatusTemporaryRedirect)
 | 
			
		||||
@ -42,6 +52,13 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the current page is only "/admin/", redirect to "/admin/browse/contents"
 | 
			
		||||
		if r.URL.Path == "/admin/" {
 | 
			
		||||
			http.Redirect(w, r, "/admin/browse/content/", http.StatusTemporaryRedirect)
 | 
			
		||||
			return 0, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Serve the static assets
 | 
			
		||||
		if page == "assets" {
 | 
			
		||||
			filename := strings.Replace(r.URL.Path, "/admin/", "", 1)
 | 
			
		||||
			file, err := assets.Asset(filename)
 | 
			
		||||
@ -50,28 +67,36 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
 | 
			
		||||
				return 404, nil
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Get the file extension ant its mime type
 | 
			
		||||
			extension := filepath.Ext(filename)
 | 
			
		||||
			mime := mime.TypeByExtension(extension)
 | 
			
		||||
 | 
			
		||||
			header := w.Header()
 | 
			
		||||
			header.Set("Content-Type", mime)
 | 
			
		||||
 | 
			
		||||
			// Write the header with the Content-Type and write the file
 | 
			
		||||
			// content to the buffer
 | 
			
		||||
			w.Header().Set("Content-Type", mime)
 | 
			
		||||
			w.Write(file)
 | 
			
		||||
			return 200, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if page == "browse" {
 | 
			
		||||
			code, err = browse.Execute(w, r)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if page == "edit" {
 | 
			
		||||
			code, err = edit.Execute(w, r)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the url matches exactly with /admin/settings/ serve that page
 | 
			
		||||
		// page variable isn't used here to avoid people using URLs like
 | 
			
		||||
		// "/admin/settings/something".
 | 
			
		||||
		if r.URL.Path == "/admin/settings/" {
 | 
			
		||||
			code, err = settings.Execute(w, r)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Browse page
 | 
			
		||||
		if page == "browse" {
 | 
			
		||||
			code, err = browse.Execute(w, r)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Edit page
 | 
			
		||||
		if page == "edit" {
 | 
			
		||||
			code, err = edit.Execute(w, r)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Whenever the header "X-Refenerate" is true, the website should be
 | 
			
		||||
		// regenerated. Used in edit and settings, for example.
 | 
			
		||||
		if r.Header.Get("X-Regenerate") == "true" {
 | 
			
		||||
			commands.Execute()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "animate.css": "^3.4.0",
 | 
			
		||||
    "codemirror": "^5.6.0",
 | 
			
		||||
    "font-awesome": "^4.4.0",
 | 
			
		||||
    "jquery": "^2.1.4",
 | 
			
		||||
    "jquery-serializejson": "^2.5.0",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								page/page.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								page/page.go
									
									
									
									
									
								
							@ -21,6 +21,7 @@ var funcMap = template.FuncMap{
 | 
			
		||||
// Page type
 | 
			
		||||
type Page struct {
 | 
			
		||||
	Name  string
 | 
			
		||||
	Class string
 | 
			
		||||
	Body  interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,7 +38,11 @@ func (p *Page) Render(w http.ResponseWriter, r *http.Request, templates ...strin
 | 
			
		||||
	return 200, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetTemplate is used to get a ready to use template based on the url and on
 | 
			
		||||
// other sent templates
 | 
			
		||||
func GetTemplate(r *http.Request, templates ...string) (*template.Template, error) {
 | 
			
		||||
	// If this is a pjax request, use the minimal template to send only
 | 
			
		||||
	// the main content
 | 
			
		||||
	if r.Header.Get("X-PJAX") == "true" {
 | 
			
		||||
		templates = append(templates, "base_minimal")
 | 
			
		||||
	} else {
 | 
			
		||||
@ -46,14 +51,19 @@ func GetTemplate(r *http.Request, templates ...string) (*template.Template, erro
 | 
			
		||||
 | 
			
		||||
	var tpl *template.Template
 | 
			
		||||
 | 
			
		||||
	// For each template, add it to the the tpl variable
 | 
			
		||||
	for i, t := range templates {
 | 
			
		||||
		// Get the template from the assets
 | 
			
		||||
		page, err := assets.Asset("templates/" + t + templateExtension)
 | 
			
		||||
 | 
			
		||||
		// Check if there is some error. If so, the template doesn't exist
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Print(err)
 | 
			
		||||
			return new(template.Template), err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If it's the first iteration, creates a new template and add the
 | 
			
		||||
		// functions map
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			tpl, err = template.New(t).Funcs(funcMap).Parse(string(page))
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,7 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
			
		||||
 | 
			
		||||
		page := new(page.Page)
 | 
			
		||||
		page.Name = "Settings"
 | 
			
		||||
		page.Class = "settings"
 | 
			
		||||
		page.Body = f
 | 
			
		||||
		return page.Render(w, r, "settings", "frontmatter")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html class="no-js" lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="utf-8">
 | 
			
		||||
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
@ -17,16 +16,14 @@
 | 
			
		||||
  <nav>
 | 
			
		||||
    <ul>
 | 
			
		||||
      <li><a href="/"><i class="fa fa-home fa-lg"></i> Home</a></li>
 | 
			
		||||
      <li><a href="/admin/browse/content"><i class="fa fa-newspaper-o"></i> Content</a></li>
 | 
			
		||||
      <li><a href="/admin/browse"><i class="fa fa-folder-o"></i> Browse</a></li>
 | 
			
		||||
      <li><a href="/admin/settings"><i class="fa fa-cog"></i> Settings</a></li>
 | 
			
		||||
      <li><a href="/admin/browse/content/"><i class="fa fa-newspaper-o"></i> Content</a></li>
 | 
			
		||||
      <li><a href="/admin/browse/"><i class="fa fa-folder-o"></i> Browse</a></li>
 | 
			
		||||
      <li><a href="/admin/settings/"><i class="fa fa-cog"></i> Settings</a></li>
 | 
			
		||||
      <li><a id="logout" href="#logout"><i class="fa fa-sign-out"></i> Logout</a></li>
 | 
			
		||||
    </ul>
 | 
			
		||||
  </nav>
 | 
			
		||||
  <div class="main" id="container">
 | 
			
		||||
  {{ template "content" . }}
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div class="container data">
 | 
			
		||||
      <textarea name="content" class="scroll">{{ .Content }}</textarea>
 | 
			
		||||
      <textarea id="content-area" name="content" class="scroll">{{ .Content }}</textarea>
 | 
			
		||||
      <div id="preview-area" class="scroll hidden"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@
 | 
			
		||||
  {{ if not (eq $value.Parent.Type "array") }}
 | 
			
		||||
  <label for="{{ $value.Name }}">{{ splitCapitalize $value.Title }}</label>
 | 
			
		||||
  {{ end }}
 | 
			
		||||
  <input name="{{ $value.Name }}" id="{{ $value.Name }}" value="{{ $value.Content }}"></input><br>
 | 
			
		||||
  <input name="{{ $value.Name }}:auto" id="{{ $value.Name }}" value="{{ $value.Content }}"></input><br>
 | 
			
		||||
  {{ end }}
 | 
			
		||||
{{ end }}
 | 
			
		||||
{{ end }}
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,13 @@
 | 
			
		||||
{{ define "content" }}
 | 
			
		||||
<header>
 | 
			
		||||
  <div class="content">
 | 
			
		||||
    <h1>Settings</h1>
 | 
			
		||||
  </div>
 | 
			
		||||
</header>
 | 
			
		||||
 | 
			
		||||
<main>
 | 
			
		||||
{{ with .Body }}
 | 
			
		||||
<div class="content">
 | 
			
		||||
  <h1>Settings</h1>
 | 
			
		||||
  <form method="POST" action="/admin/settings">
 | 
			
		||||
  {{ template "frontmatter" . }}
 | 
			
		||||
  <input type="submit" data-message="Settings updated." data-regenerate="true" value="Save">
 | 
			
		||||
 | 
			
		||||
@ -24,38 +24,48 @@ func Dict(values ...interface{}) (map[string]interface{}, error) {
 | 
			
		||||
	return dict, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsMap checks if some variable is a map
 | 
			
		||||
func IsMap(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Map
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSlice checks if some variable is a slice
 | 
			
		||||
func IsSlice(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Slice
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsArray checks if some variable is an array
 | 
			
		||||
func IsArray(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Array
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsString checks if some variable is a string
 | 
			
		||||
func IsString(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsInt checks if some variable is an integer
 | 
			
		||||
func IsInt(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsBool checks if some variable is a boolean
 | 
			
		||||
func IsBool(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsInterface checks if some variable is an interface
 | 
			
		||||
func IsInterface(sth interface{}) bool {
 | 
			
		||||
	return reflect.ValueOf(sth).Kind() == reflect.Interface
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsMarkdownFile checks if a filename belongs to a markdown file
 | 
			
		||||
func IsMarkdownFile(filename string) bool {
 | 
			
		||||
	return strings.HasSuffix(filename, ".markdown") || strings.HasSuffix(filename, ".md")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SplitCapitalize splits a string by its uppercase letters and capitalize the
 | 
			
		||||
// first letter of the string
 | 
			
		||||
func SplitCapitalize(name string) string {
 | 
			
		||||
	var words []string
 | 
			
		||||
	l := 0
 | 
			
		||||
@ -79,6 +89,7 @@ func SplitCapitalize(name string) string {
 | 
			
		||||
	return name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseComponents parses the components of an URL creating an array
 | 
			
		||||
func ParseComponents(r *http.Request) []string {
 | 
			
		||||
	//The URL that the user queried.
 | 
			
		||||
	path := r.URL.Path
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user