fileadmin

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

README

fileadmin

Tests Status Go Report Card PkgGoDev

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). You can find a copy of the license at https://www.gnu.org/licenses/agpl-3.0.en.html

For commercial use, please use my contact page to obtain a commercial license.

Introduction

Admin interface for github.com/dracory/filesystem. Provides a ready-to-use admin panel for managing files and directories stored in a SQL-backed filesystem.

Modeled after github.com/dracory/shopadmin, github.com/dracory/blogadmin, and github.com/dracory/logadmin — same folder-per-controller pattern, same UiConfig/UiBase conventions.

Features

  • File browsing — navigate directories, view file metadata
  • File upload — upload files up to 50MB
  • File operations — rename, clone (duplicate), delete
  • Directory operations — create, delete directories
  • Bulk actions — bulk move and bulk delete with item selection
  • Move destinations — filtered list of valid move targets (excludes moving a directory into itself or its subdirectories)
  • Path traversal protection — all paths are validated to prevent directory traversal attacks
  • Custom layouts — bring your own layout via FuncLayout
  • Bootstrap + Vue CDN — default UI works out of the box

Installation

go get github.com/dracory/fileadmin

Quick Start

package main

import (
    "log/slog"
    "net/http"
    "os"

    "github.com/dracory/fileadmin"
    "github.com/dracory/filesystem"
)

func main() {
    storage, err := filesystem.NewStorage(filesystem.Disk{
        DiskName:  filesystem.DRIVER_SQL,
        Driver:    filesystem.DRIVER_SQL,
        Url:       "/files",
        DB:        yourDB,
        TableName: "snv_files_file",
    })
    if err != nil {
        log.Fatal(err)
    }

    admin, err := fileadmin.New(fileadmin.AdminOptions{
        Storage:      storage,
        RootDirPath:  "/uploads",
        AdminHomeURL: "/admin",
        FileAdminURL: "/admin/file-manager",
    })
    if err != nil {
        log.Fatal(err)
    }

    http.Handle("/admin/file-manager", http.HandlerFunc(admin.Handle))
    http.ListenAndServe(":8080", nil)
}

See example/ for a complete runnable server with in-memory SQLite.

Integration with a Router

fileadmin.AdminInterface exposes Handle(w, r), which is an http.HandlerFunc-compatible method. Wire it into any router that accepts standard http.Handler:

// stdlib
mux.Handle("/admin/file-manager", http.HandlerFunc(admin.Handle))

// github.com/dracory/rtr
route := rtr.NewRoute().
    SetName("Admin > File Manager").
    SetPath("/admin/file-manager").
    SetHTMLHandler(admin.Handle)

Custom Layout

By default, fileadmin renders a bare-bones HTML page with Bootstrap and Vue from CDN. To embed the admin inside your own layout (branding, menus, etc.), provide FuncLayout:

admin, _ := fileadmin.New(fileadmin.AdminOptions{
    Storage:     storage,
    RootDirPath: "/uploads",
    FuncLayout: func(w http.ResponseWriter, r *http.Request, title, body string, opts struct {
        Styles     []string
        StyleURLs  []string
        Scripts    []string
        ScriptURLs []string
    }) string {
        return myLayout(w, r, title, body, opts)
    },
})

The anonymous struct matches shopadmin/blogadmin/logadmin exactly, so you can reuse your existing layout function.

Testing

go test ./...

Tests use an in-memory SQLite database via modernc.org/sqlite — no external services required.

Documentation

Overview

Package fileadmin provides a standalone file admin interface following the folder-per-controller pattern. Each controller is in its own subfolder and handles its own views and AJAX data.

This module is modeled on github.com/dracory/shopadmin, github.com/dracory/blogadmin, and github.com/dracory/logadmin.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrStorageRequired is returned when Storage is not provided
	ErrStorageRequired = errors.New("storage is required")
)

Common errors

Functions

This section is empty.

Types

type AdminInterface

type AdminInterface interface {
	Handle(w http.ResponseWriter, r *http.Request)
}

AdminInterface defines the interface for the file admin

func New

func New(opts AdminOptions) (AdminInterface, error)

New creates a new file admin instance. Returns ErrStorageRequired if Storage is nil.

type AdminOptions

type AdminOptions struct {
	// Storage is the filesystem.StorageInterface (required)
	Storage filesystem.StorageInterface

	// RootDirPath is the root directory for file operations (required).
	// Typically derived from the host project's media root config.
	// e.g. "/uploads"
	RootDirPath string

	// FuncLayout is an optional function to render the admin interface
	// inside your own layout (branding, menus, etc.). It receives the
	// request and response writer so the host project can access request
	// context (auth user, locale, etc.) when rendering the layout.
	FuncLayout func(w http.ResponseWriter, r *http.Request, title string, body string, options struct {
		Styles     []string
		StyleURLs  []string
		Scripts    []string
		ScriptURLs []string
	}) string

	// AdminHomeURL is the URL for the admin home page (default: "/admin")
	AdminHomeURL string

	// FileAdminURL is the base URL for file admin (default: "/admin/file-manager")
	FileAdminURL string

	// AuthUserID returns the authenticated user ID from the request.
	// If it returns "", the user is treated as unauthenticated.
	AuthUserID func(r *http.Request) string
}

AdminOptions contains all dependencies and configuration for the file admin.

Storage and RootDirPath replace the in-repo version's Registry field (which was app.AppInterface). This matches the shopadmin/blogadmin/logadmin convention where dependencies are passed directly.

FuncLayout is an optional function to render the admin interface inside your own layout (branding, menus, etc.). It receives the request and response writer so the host project can access request context (auth user, locale, etc.) when rendering the layout. If nil, a default bare-bones HTML page is used (Bootstrap + Vue CDN). Uses anonymous struct to match shopadmin/blogadmin/logadmin exactly, so consumers can reuse their existing layout function for fileadmin.

Directories

Path Synopsis
Example fileadmin server.
Example fileadmin server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL