Merge branch 'feature/theme' into develop
This commit is contained in:
commit
76a65f0e3a
|
@ -7,8 +7,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Host string `env:"HOST" envDefault:"0.0.0.0"`
|
|
||||||
ContentDir string `env:"CONTENT_DIR" envDefault:"content/"`
|
ContentDir string `env:"CONTENT_DIR" envDefault:"content/"`
|
||||||
|
Host string `env:"HOST" envDefault:"0.0.0.0"`
|
||||||
|
ThemeDir string `env:"THEME_DIR" envDefault:"theme/"`
|
||||||
Port uint16 `env:"PORT" envDefault:"3000"`
|
Port uint16 `env:"PORT" envDefault:"3000"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package theme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Repository interface {
|
||||||
|
// TODO(toby3d): use Page context to find it's specific template.
|
||||||
|
Get(ctx context.Context) (*template.Template, error)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package fs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io/fs"
|
||||||
|
|
||||||
|
"source.toby3d.me/toby3d/home/internal/theme"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fileSystemThemeRepository struct {
|
||||||
|
dir fs.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileSystemThemeRepository(dir fs.FS) theme.Repository {
|
||||||
|
return &fileSystemThemeRepository{
|
||||||
|
dir: dir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *fileSystemThemeRepository) Get(ctx context.Context) (*template.Template, error) {
|
||||||
|
tpl, err := template.New("").ParseFS(repo.dir, "baseof.html", "single.html")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot find baseof.html: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpl, nil
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package theme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"html/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UseCase interface {
|
||||||
|
Do(ctx context.Context) (*template.Template, error)
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package usecase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
|
||||||
|
"source.toby3d.me/toby3d/home/internal/theme"
|
||||||
|
)
|
||||||
|
|
||||||
|
type themeUseCase struct {
|
||||||
|
themes theme.Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewThemeUseCase(themes theme.Repository) theme.UseCase {
|
||||||
|
return &themeUseCase{
|
||||||
|
themes: themes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ucase *themeUseCase) Do(ctx context.Context) (*template.Template, error) {
|
||||||
|
out, err := ucase.themes.Get(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot find theme: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.Lookup("baseof"), nil
|
||||||
|
}
|
55
main.go
55
main.go
|
@ -29,9 +29,15 @@ import (
|
||||||
pageucase "source.toby3d.me/toby3d/home/internal/page/usecase"
|
pageucase "source.toby3d.me/toby3d/home/internal/page/usecase"
|
||||||
sitefsrepo "source.toby3d.me/toby3d/home/internal/site/repository/fs"
|
sitefsrepo "source.toby3d.me/toby3d/home/internal/site/repository/fs"
|
||||||
siteucase "source.toby3d.me/toby3d/home/internal/site/usecase"
|
siteucase "source.toby3d.me/toby3d/home/internal/site/usecase"
|
||||||
"source.toby3d.me/toby3d/home/web/template"
|
themefsrepo "source.toby3d.me/toby3d/home/internal/theme/repository/fs"
|
||||||
|
themeucase "source.toby3d.me/toby3d/home/internal/theme/usecase"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
Site *domain.Site
|
||||||
|
Page *domain.Page
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
config = new(domain.Config)
|
config = new(domain.Config)
|
||||||
logger = log.New(os.Stdout, "home\t", log.Lmsgprefix|log.LstdFlags|log.LUTC)
|
logger = log.New(os.Stdout, "home\t", log.Lmsgprefix|log.LstdFlags|log.LUTC)
|
||||||
|
@ -49,21 +55,26 @@ func init() {
|
||||||
logger.Fatalln("cannot unmarshal configuration into domain:", err)
|
logger.Fatalln("cannot unmarshal configuration into domain:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ContentDir, err = filepath.Abs(filepath.Clean(config.ContentDir)); err != nil {
|
for _, dir := range []*string{
|
||||||
logger.Fatalf("cannot format '%s' content dir path into absolute path: %s", config.ContentDir, err)
|
&config.ContentDir,
|
||||||
}
|
&config.ThemeDir,
|
||||||
|
} {
|
||||||
if _, err = os.Stat(config.ContentDir); err != nil {
|
if *dir, err = filepath.Abs(filepath.Clean(*dir)); err != nil {
|
||||||
if errors.Is(err, os.ErrExist) {
|
logger.Fatalf("cannot format '%s' into absolute path: %s", *dir, err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
if _, err = os.Stat(*dir); err != nil {
|
||||||
logger.Fatalln("cannot check directory path for content:", err)
|
if errors.Is(err, os.ErrExist) {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err = os.MkdirAll(config.ContentDir, os.ModePerm); err != nil {
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
logger.Fatalln("cannot create directory for content:", err)
|
logger.Fatalf("cannot check '%s' path: %v", *dir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.MkdirAll(*dir, os.ModePerm); err != nil {
|
||||||
|
logger.Fatalf("cannot create directory on '%s': %v", *dir, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +84,10 @@ func main() {
|
||||||
matcher := language.NewMatcher(message.DefaultCatalog.Languages())
|
matcher := language.NewMatcher(message.DefaultCatalog.Languages())
|
||||||
|
|
||||||
contentDir := os.DirFS(config.ContentDir)
|
contentDir := os.DirFS(config.ContentDir)
|
||||||
|
themeDir := os.DirFS(config.ThemeDir)
|
||||||
|
|
||||||
|
themes := themefsrepo.NewFileSystemThemeRepository(themeDir)
|
||||||
|
themer := themeucase.NewThemeUseCase(themes)
|
||||||
|
|
||||||
sites := sitefsrepo.NewFileSystemSiteRepository(contentDir)
|
sites := sitefsrepo.NewFileSystemSiteRepository(contentDir)
|
||||||
siter := siteucase.NewSiteUseCase(sites)
|
siter := siteucase.NewSiteUseCase(sites)
|
||||||
|
@ -104,8 +119,20 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tpl, err := themer.Do(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
||||||
template.WriteTemplate(w, template.NewPage(template.NewBaseOf(site), page))
|
if err = tpl.Execute(w, &Context{
|
||||||
|
Site: site,
|
||||||
|
Page: page,
|
||||||
|
}); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
ErrorLog: logger,
|
ErrorLog: logger,
|
||||||
BaseContext: func(ln net.Listener) context.Context { return ctx },
|
BaseContext: func(ln net.Listener) context.Context { return ctx },
|
||||||
|
|
Loading…
Reference in New Issue