diff --git a/dbmodels/agent.go b/dbmodels/agent.go index 7a828b0..f380285 100644 --- a/dbmodels/agent.go +++ b/dbmodels/agent.go @@ -1,11 +1,7 @@ package dbmodels import ( - "slices" - "github.com/pocketbase/pocketbase/core" - "golang.org/x/text/collate" - "golang.org/x/text/language" ) var _ core.RecordProxy = (*Agent)(nil) @@ -115,10 +111,3 @@ func (a *Agent) SetEditState(editState string) { func (a *Agent) Comment() string { return a.GetString(COMMENT_FIELD) } - -func SortAgentsByName(series []*Agent) { - collator := collate.New(language.German) - slices.SortFunc(series, func(i, j *Agent) int { - return collator.CompareString(i.Name(), j.Name()) - }) -} diff --git a/dbmodels/agents.go b/dbmodels/agents.go index e2a2b80..69fd33e 100644 --- a/dbmodels/agents.go +++ b/dbmodels/agents.go @@ -1,10 +1,17 @@ package dbmodels import ( + "slices" + "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" + "golang.org/x/text/collate" + "golang.org/x/text/language" ) +type AgentsEntries map[string][]*REntriesAgents +type AgentsContents map[string][]*RContentsAgents + func AgentForId(app core.App, id string) (*Agent, error) { agent := &Agent{} err := app.RecordQuery(AGENTS_TABLE). @@ -15,3 +22,193 @@ func AgentForId(app core.App, id string) (*Agent, error) { } return agent, nil } + +func AgentsForEntries(app core.App, entries []*Entry) (map[string]*Agent, AgentsEntries, error) { + eids := []any{} + for _, e := range entries { + eids = append(eids, e.Id) + } + + relations := []*REntriesAgents{} + err := app.RecordQuery(RelationTableName(ENTRIES_TABLE, AGENTS_TABLE)). + Where(dbx.HashExp{ENTRIES_TABLE: eids}). + All(&relations) + if err != nil { + return nil, nil, err + } + + agentIds := []any{} + for _, r := range relations { + agentIds = append(agentIds, r.Agent()) + } + + agents := []*Agent{} + err = app.RecordQuery(AGENTS_TABLE). + Where(dbx.HashExp{ID_FIELD: agentIds}). + All(&agents) + if err != nil { + return nil, nil, err + } + + agentsMap := make(map[string]*Agent, len(agents)) + for _, a := range agents { + agentsMap[a.Id] = a + } + + relationMap := make(map[string][]*REntriesAgents, len(entries)) + for _, r := range relations { + relationMap[r.Entry()] = append(relationMap[r.Entry()], r) + } + + return agentsMap, relationMap, nil +} + +func AgentsForContents(app core.App, contents []*Content) (map[string]*Agent, AgentsContents, error) { + cids := []any{} + for _, c := range contents { + cids = append(cids, c.Id) + } + + relations := []*RContentsAgents{} + err := app.RecordQuery(RelationTableName(CONTENTS_TABLE, AGENTS_TABLE)). + Where(dbx.HashExp{CONTENTS_TABLE: cids}). + All(&relations) + if err != nil { + return nil, nil, err + } + + agentIds := []any{} + for _, r := range relations { + agentIds = append(agentIds, r.Agent()) + } + + agents := []*Agent{} + err = app.RecordQuery(AGENTS_TABLE). + Where(dbx.HashExp{ID_FIELD: agentIds}). + All(&agents) + if err != nil { + return nil, nil, err + } + + agentsMap := make(map[string]*Agent, len(agents)) + for _, a := range agents { + agentsMap[a.Id] = a + } + + relationMap := make(map[string][]*RContentsAgents, len(contents)) + for _, r := range relations { + relationMap[r.Content()] = append(relationMap[r.Content()], r) + } + + return agentsMap, relationMap, nil +} + +func LettersForAgents(app core.App) ([]string, error) { + letters := []core.Record{} + ids := []string{} + + err := app.RecordQuery(AGENTS_TABLE). + Select("upper(substr(" + AGENTS_NAME_FIELD + ", 1, 1)) AS id"). + Distinct(true). + All(&letters) + if err != nil { + return nil, err + } + + for _, l := range letters { + ids = append(ids, l.GetString("id")) + } + + collator := collate.New(language.German, collate.Loose) + collator.SortStrings(ids) + + return ids, nil +} + +func AgentsForLetter(app core.App, letter string) ([]*Agent, error) { + agents := []*Agent{} + err := app.RecordQuery(AGENTS_TABLE). + Where(dbx.Like(AGENTS_NAME_FIELD, letter).Match(false, true)). + OrderBy(AGENTS_NAME_FIELD). + All(&agents) + if err != nil { + return nil, err + } + + return agents, nil +} + +func SortAgentsByName(series []*Agent) { + collator := collate.New(language.German, collate.Loose) + slices.SortFunc(series, func(i, j *Agent) int { + return collator.CompareString(i.Name(), j.Name()) + }) +} + +func BasicSearchAgents(app core.App, query string) ([]*Agent, []*Agent, error) { + agents, err := TitleSearchAgents(app, query) + if err != nil { + return nil, nil, err + } + + altagents, err := AltSearchAgents(app, query) + if err != nil { + return nil, nil, err + } + return agents, altagents, nil +} + +func TitleSearchAgents(app core.App, query string) ([]*Agent, error) { + agents := []*Agent{} + err := app.RecordQuery(AGENTS_TABLE). + Where(dbx.Like(AGENTS_NAME_FIELD, query).Match(true, true)). + OrWhere(dbx.Like(AGENTS_PSEUDONYMS_FIELD, query).Match(true, true)). + OrderBy(AGENTS_NAME_FIELD). + All(&agents) + if err != nil { + return nil, err + } + + return agents, nil +} + +func AltSearchAgents(app core.App, query string) ([]*Agent, error) { + agents := []*Agent{} + err := app.RecordQuery(AGENTS_TABLE). + Where(dbx.Like(ANNOTATION_FIELD, query).Match(true, true)). + OrderBy(AGENTS_NAME_FIELD). + All(&agents) + if err != nil { + return nil, err + } + + return agents, nil +} + +func AgentsForProfession(app core.App, profession string, letter string) ([]*Agent, error) { + agents := []*Agent{} + err := app.RecordQuery(AGENTS_TABLE). + Where(dbx.Like(AGENTS_NAME_FIELD, letter).Match(false, true)). + AndWhere(dbx.Like(AGENTS_PROFESSION_FIELD, profession).Match(true, true)). + OrderBy(AGENTS_NAME_FIELD). + All(&agents) + if err != nil { + return nil, err + } + + return agents, nil +} + +func AgentsForOrg(app core.App, org bool, letter string) ([]*Agent, error) { + agents := []*Agent{} + err := app.RecordQuery(AGENTS_TABLE). + Where(dbx.Like(AGENTS_NAME_FIELD, letter).Match(false, true)). + AndWhere(dbx.HashExp{AGENTS_CORP_FIELD: org}). + OrderBy(AGENTS_NAME_FIELD). + All(&agents) + if err != nil { + return nil, err + } + + return agents, nil +} diff --git a/dbmodels/contents.go b/dbmodels/contents.go new file mode 100644 index 0000000..81f5bac --- /dev/null +++ b/dbmodels/contents.go @@ -0,0 +1,86 @@ +package dbmodels + +import ( + "slices" + "strings" + + "github.com/pocketbase/dbx" + "github.com/pocketbase/pocketbase/core" +) + +type ContentsAgents map[string][]*RContentsAgents + +func ContentsForEntry(app core.App, entry *Entry) ([]*Content, error) { + contents := []*Content{} + err := app.RecordQuery(CONTENTS_TABLE). + Where(dbx.HashExp{ENTRIES_TABLE: entry.Id}). + All(&contents) + if err != nil { + return nil, err + } + + slices.SortFunc(contents, func(i, j *Content) int { + r := i.Numbering() - j.Numbering() + if r == 0 { + return 0 + } + if r < 0 { + return -1 + } + return 1 + }) + + return contents, nil +} + +func ContentsForAgent(app core.App, agentId string) ([]*Content, error) { + relations := []*RContentsAgents{} + err := app.RecordQuery(RelationTableName(CONTENTS_TABLE, AGENTS_TABLE)). + Where(dbx.HashExp{AGENTS_TABLE: agentId}). + All(&relations) + if err != nil { + return nil, err + } + + cids := []any{} + for _, r := range relations { + cids = append(cids, r.Content()) + } + + contents := []*Content{} + err = app.RecordQuery(CONTENTS_TABLE). + Where(dbx.HashExp{ID_FIELD: cids}). + All(&contents) + if err != nil { + return nil, err + } + + return contents, nil +} + +func SortContentsByEntryNumbering(contents []*Content, entries map[string]*Entry) { + slices.SortFunc(contents, func(i, j *Content) int { + ii, iok := entries[i.Entry()] + ij, jok := entries[j.Entry()] + if iok && jok { + ret := ii.Year() - ij.Year() + if ret != 0 { + return ret + } + + ret = strings.Compare(ii.PreferredTitle(), ij.PreferredTitle()) + if ret != 0 { + return ret + } + } + + r := i.Numbering() - j.Numbering() + if r == 0 { + return 0 + } + if r < 0 { + return -1 + } + return 1 + }) +} diff --git a/dbmodels/entries.go b/dbmodels/entries.go index 680bd68..6b539b8 100644 --- a/dbmodels/entries.go +++ b/dbmodels/entries.go @@ -88,3 +88,36 @@ func EntryForId(app core.App, id string) (*Entry, error) { } return entry, nil } + +func EntryForMusenalmID(app core.App, id string) (*Entry, error) { + entry := &Entry{} + err := app.RecordQuery(ENTRIES_TABLE). + Where(dbx.HashExp{MUSENALMID_FIELD: id}). + One(entry) + if err != nil { + return nil, err + } + return entry, nil +} + +func EntriesForContents(app core.App, contents []*Content) (map[string]*Entry, error) { + cids := []any{} + for _, c := range contents { + cids = append(cids, c.Entry()) + } + + entries := []*Entry{} + err := app.RecordQuery(ENTRIES_TABLE). + Where(dbx.HashExp{ID_FIELD: cids}). + All(&entries) + if err != nil { + return nil, err + } + + entriesMap := make(map[string]*Entry, len(entries)) + for _, e := range entries { + entriesMap[e.Id] = e + } + + return entriesMap, nil +} diff --git a/dbmodels/places.go b/dbmodels/places.go index 82f567e..55925ba 100644 --- a/dbmodels/places.go +++ b/dbmodels/places.go @@ -38,3 +38,29 @@ func PlaceForId(app core.App, id string) (*Place, error) { } return place, nil } + +func PlacesForEntry(app core.App, entry *Entry) (map[string]*Place, error) { + ids := []any{} + places := map[string]*Place{} + + for _, r := range entry.Places() { + ids = append(ids, r) + } + if len(ids) == 0 { + return places, nil + } + + p := []*Place{} + err := app.RecordQuery(PLACES_TABLE). + Where(dbx.HashExp{ID_FIELD: ids}). + All(&p) + if err != nil { + return nil, err + } + + for _, place := range p { + places[place.Id] = place + } + + return places, nil +} diff --git a/dbmodels/seriesses.go b/dbmodels/seriesses.go index 879b9d2..5aa6177 100644 --- a/dbmodels/seriesses.go +++ b/dbmodels/seriesses.go @@ -68,7 +68,7 @@ func IDsForSeriesses(series []*Series) []any { func makeMapForEnrySeries(relations []*REntriesSeries, entries map[string]*Entry) SeriesEntries { m := map[string][]*REntriesSeries{} for _, r := range relations { - m[r.Id] = append(m[r.Id], r) + m[r.Series()] = append(m[r.Series()], r) } for _, rel := range m { @@ -111,8 +111,8 @@ func EntriesForSeriesses(app core.App, series []*Series) ( smap := map[string][]*REntriesSeries{} for _, r := range relations { - series := NewREntriesSeries(r) - smap[series.Id] = append(smap[series.Id], series) + rel := NewREntriesSeries(r) + smap[rel.Series()] = append(smap[rel.Series()], rel) } for _, rel := range smap { diff --git a/helpers/functions/templates.go b/helpers/functions/templates.go new file mode 100644 index 0000000..d735aa8 --- /dev/null +++ b/helpers/functions/templates.go @@ -0,0 +1,5 @@ +package functions + +func Arr(els ...any) []any { + return els +} diff --git a/pages/404.go b/pages/404.go new file mode 100644 index 0000000..3f4398e --- /dev/null +++ b/pages/404.go @@ -0,0 +1,48 @@ +package pages + +import ( + "net/http" + "strings" + + "github.com/Theodor-Springmann-Stiftung/musenalm/app" + "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/templating" + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/router" +) + +const URL_ERROR_404 = "/errors/404/" + +func init() { + rp := &Error404Page{ + Page: pagemodels.Page{ + Name: URL_ERROR_404, + }, + } + app.Register(rp) +} + +type Error404Page struct { + pagemodels.Page +} + +func (p *Error404Page) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { + router.GET(URL_ERROR_404, func(e *core.RequestEvent) error { + return Error404(e, engine, nil) + }) + return nil +} + +func Error404(e *core.RequestEvent, engine *templating.Engine, err error) error { + data := make(map[string]interface{}) + var sb strings.Builder + if err != nil { + e.App.Logger().Error("404 error fetching URL!", "error", err, "request", e.Request.URL) + data["Error"] = err.Error() + } + err = engine.Render(&sb, URL_ERROR_404, data, "default") + if err != nil { + return e.String(http.StatusInternalServerError, err.Error()) + } + return e.HTML(http.StatusNotFound, sb.String()) +} diff --git a/pages/almanach.go b/pages/almanach.go new file mode 100644 index 0000000..fcce372 --- /dev/null +++ b/pages/almanach.go @@ -0,0 +1,99 @@ +package pages + +import ( + "net/http" + "strings" + + "github.com/Theodor-Springmann-Stiftung/musenalm/app" + "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/templating" + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/router" +) + +const ( + URL_ALMANACH = "/almanach/{id}" + TEMPLATE_ALMANACH = "/almanach/" +) + +func init() { + rp := &AlmanachPage{ + Page: pagemodels.Page{ + Name: pagemodels.P_REIHEN_NAME, + }, + } + app.Register(rp) +} + +type AlmanachPage struct { + pagemodels.Page +} + +func (p *AlmanachPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { + router.GET(URL_ALMANACH, func(e *core.RequestEvent) error { + id := e.Request.PathValue("id") + data := make(map[string]interface{}) + entry, err := dbmodels.EntryForMusenalmID(app, id) + if err != nil { + return Error404(e, engine, err) + } + data["entry"] = entry + + series, srelations, _, err := dbmodels.SeriesForEntries(app, []*dbmodels.Entry{entry}) + if err != nil { + return Error404(e, engine, err) + } + + s := map[string]*dbmodels.Series{} + for _, r := range series { + s[r.Id] = r + } + + data["srelations"] = srelations + data["series"] = s + + places, err := dbmodels.PlacesForEntry(app, entry) + if err != nil { + return Error404(e, engine, err) + } + data["places"] = places + + contents, err := dbmodels.ContentsForEntry(app, entry) + if err != nil { + return Error404(e, engine, err) + } + data["contents"] = contents + + agents, arelations, err := dbmodels.AgentsForEntries(app, []*dbmodels.Entry{entry}) + if err != nil { + return Error404(e, engine, err) + } + data["arelations"] = arelations + + if len(contents) > 0 { + cagents, crelations, err := dbmodels.AgentsForContents(app, contents) + if err != nil { + return Error404(e, engine, err) + } + data["crelations"] = crelations + for k, v := range cagents { + agents[k] = v + } + } + data["agents"] = agents + + return p.Get(e, engine, data) + }) + + return nil +} + +func (p *AlmanachPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error { + var builder strings.Builder + err := engine.Render(&builder, TEMPLATE_ALMANACH, data) + if err != nil { + return Error404(request, engine, err) + } + return request.HTML(http.StatusOK, builder.String()) +} diff --git a/pages/index.go b/pages/index.go index 78bbd75..d36095b 100644 --- a/pages/index.go +++ b/pages/index.go @@ -24,14 +24,6 @@ type IndexPage struct { pagemodels.Page } -func (p *IndexPage) Up(app core.App) error { - return nil -} - -func (p *IndexPage) Down(app core.App) error { - return nil -} - func (p *IndexPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { router.GET("/{$}", func(e *core.RequestEvent) error { var builder strings.Builder diff --git a/pages/person.go b/pages/person.go new file mode 100644 index 0000000..42cdd36 --- /dev/null +++ b/pages/person.go @@ -0,0 +1,91 @@ +package pages + +import ( + "strings" + + "github.com/Theodor-Springmann-Stiftung/musenalm/app" + "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/templating" + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/router" +) + +const ( + URL_PERSON = "/person/{id}" + TEMPLATE_PERSON = "/person/" +) + +func init() { + rp := &PersonPage{ + Page: pagemodels.Page{ + Name: URL_PERSON, + }, + } + app.Register(rp) +} + +type PersonPage struct { + pagemodels.Page +} + +func (p *PersonPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { + router.GET(URL_PERSON, func(e *core.RequestEvent) error { + person := e.Request.PathValue("id") + data := make(map[string]interface{}) + data[PARAM_PERSON] = person + + agent, err := dbmodels.AgentForId(app, person) + if err != nil { + return Error404(e, engine, err) + } + data["a"] = agent + + series, relations, entries, err := dbmodels.SeriesForAgent(app, person) + if err != nil { + return Error404(e, engine, err) + } + + dbmodels.SortSeriessesByTitle(series) + data["series"] = series + data["relations"] = relations + data["entries"] = entries + + contents, err := dbmodels.ContentsForAgent(app, person) + if err != nil { + return Error404(e, engine, err) + } + + agents, crelations, err := dbmodels.AgentsForContents(app, contents) + if err != nil { + return Error404(e, engine, err) + } + data["agents"] = agents + data["crelations"] = crelations + + centries, err := dbmodels.EntriesForContents(app, contents) + if err != nil { + return Error404(e, engine, err) + } + data["centries"] = centries + + dbmodels.SortContentsByEntryNumbering(contents, centries) + data["contents"] = contents + + return p.Get(e, engine, data) + }) + + return nil +} + +func (p *PersonPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error { + var builder strings.Builder + err := engine.Render(&builder, TEMPLATE_PERSON, data) + if err != nil { + return Error404(request, engine, err) + } + + request.Response.Header().Set("Content-Type", "text/html") + request.Response.Write([]byte(builder.String())) + return nil +} diff --git a/pages/personen.go b/pages/personen.go new file mode 100644 index 0000000..71204ae --- /dev/null +++ b/pages/personen.go @@ -0,0 +1,152 @@ +package pages + +import ( + "net/http" + "strings" + + "github.com/Theodor-Springmann-Stiftung/musenalm/app" + "github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels" + "github.com/Theodor-Springmann-Stiftung/musenalm/templating" + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/router" +) + +const ( + URL_PERSONEN = "/personen/" + PARAM_FILTER = "filter" +) + +func init() { + rp := &PersonenPage{ + Page: pagemodels.Page{ + Name: pagemodels.P_REIHEN_NAME, + }, + } + app.Register(rp) +} + +type PersonenPage struct { + pagemodels.Page +} + +func (p *PersonenPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { + router.GET(URL_PERSONEN, func(e *core.RequestEvent) error { + if e.Request.URL.Query().Get(PARAM_SEARCH) != "" { + return p.SearchRequest(app, engine, e) + } + if e.Request.URL.Query().Get(PARAM_FILTER) != "" { + return p.FilterRequest(app, engine, e) + } + + return p.LetterRequest(app, engine, e) + }) + + return nil +} + +func (p *PersonenPage) CommonData(app core.App, data map[string]interface{}) error { + letters, err := dbmodels.LettersForAgents(app) + if err != nil { + return err + } + data["letters"] = letters + + return nil +} + +func (p *PersonenPage) FilterRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error { + filter := e.Request.URL.Query().Get(PARAM_FILTER) + letter := e.Request.URL.Query().Get(PARAM_LETTER) + if letter == "" { + letter = "A" + } + data := map[string]interface{}{} + + var err error = nil + agents := []*dbmodels.Agent{} + if filter == "org" { + agents, err = dbmodels.AgentsForOrg(app, true, letter) + } + + if filter == "noorg" { + agents, err = dbmodels.AgentsForOrg(app, false, letter) + } + + if filter == "musik" { + agents, err = dbmodels.AgentsForProfession(app, "Musik", letter) + } + + if filter == "autor" { + agents, err = dbmodels.AgentsForProfession(app, "Text", letter) + } + + if filter == "graphik" { + agents, err = dbmodels.AgentsForProfession(app, "Graphik", letter) + } + + if filter == "hrsg" { + agents, err = dbmodels.AgentsForProfession(app, "Hrsg", letter) + } + + if err != nil { + return Error404(e, engine, err) + } + dbmodels.SortAgentsByName(agents) + data["agents"] = agents + data["filter"] = filter + data["letter"] = letter + + return p.Get(e, engine, data) +} + +func (p *PersonenPage) SearchRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error { + search := e.Request.URL.Query().Get(PARAM_SEARCH) + data := map[string]interface{}{} + + agents, altagents, err := dbmodels.BasicSearchAgents(app, search) + if err != nil { + return Error404(e, engine, err) + } + + dbmodels.SortAgentsByName(agents) + dbmodels.SortAgentsByName(altagents) + + data["search"] = search + data["agents"] = agents + data["altagents"] = altagents + + return p.Get(e, engine, data) +} + +func (p *PersonenPage) LetterRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error { + letter := e.Request.URL.Query().Get(PARAM_LETTER) + if letter == "" { + letter = "A" + } + data := map[string]interface{}{} + data["letter"] = letter + + agents, err := dbmodels.AgentsForLetter(app, letter) + if err != nil { + return Error404(e, engine, err) + } + dbmodels.SortAgentsByName(agents) + data["agents"] = agents + + return p.Get(e, engine, data) +} + +func (p *PersonenPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error { + err := p.CommonData(request.App, data) + if err != nil { + return Error404(request, engine, err) + } + + var builder strings.Builder + err = engine.Render(&builder, URL_PERSONEN, data) + if err != nil { + return Error404(request, engine, err) + } + return request.HTML(http.StatusOK, builder.String()) +} diff --git a/pages/reihe.go b/pages/reihe.go index df88a4c..7ebbb33 100644 --- a/pages/reihe.go +++ b/pages/reihe.go @@ -36,13 +36,13 @@ func (p *ReihePage) Setup(router *router.Router[*core.RequestEvent], app core.Ap data := make(map[string]interface{}) reihe, err := dbmodels.SeriesForId(app, id) if err != nil { - return err + return Error404(e, engine, err) } data["series"] = reihe rmap, emap, err := dbmodels.EntriesForSeriesses(app, []*dbmodels.Series{reihe}) if err != nil { - return err + return Error404(e, engine, err) } data["relations"] = rmap @@ -58,7 +58,7 @@ func (p *ReihePage) Get(request *core.RequestEvent, engine *templating.Engine, d var builder strings.Builder err := engine.Render(&builder, TEMPLATE_REIHE, data) if err != nil { - return err + return Error404(request, engine, err) } return request.HTML(http.StatusOK, builder.String()) } diff --git a/pages/reihen.go b/pages/reihen.go index 0af5fc3..a0f2ecf 100644 --- a/pages/reihen.go +++ b/pages/reihen.go @@ -35,14 +35,6 @@ type ReihenPage struct { pagemodels.Page } -func (p *ReihenPage) Up(app core.App) error { - return nil -} - -func (p *ReihenPage) Down(app core.App) error { - return nil -} - func (p *ReihenPage) Setup(router *router.Router[*core.RequestEvent], app core.App, engine *templating.Engine) error { router.GET(URL_REIHEN, func(e *core.RequestEvent) error { search := e.Request.URL.Query().Get(PARAM_SEARCH) @@ -64,6 +56,7 @@ func (p *ReihenPage) Setup(router *router.Router[*core.RequestEvent], app core.A return p.LetterRequest(app, engine, e) }) + return nil } @@ -74,12 +67,12 @@ func (p *ReihenPage) YearRequest(app core.App, engine *templating.Engine, e *cor y, err := strconv.Atoi(year) if err != nil { - return err + return Error404(e, engine, err) } series, relations, entries, err := dbmodels.SeriesForYear(app, y) if err != nil { - return err + return Error404(e, engine, err) } data["entries"] = entries data["relations"] = relations @@ -98,7 +91,7 @@ func (p *ReihenPage) LetterRequest(app core.App, engine *templating.Engine, e *c series, err := dbmodels.SeriesForLetter(app, letter) if err != nil { - return err + return Error404(e, engine, err) } // INFO: We sort again since the query can't sort german umlauts correctly dbmodels.SortSeriessesByTitle(series) @@ -106,7 +99,7 @@ func (p *ReihenPage) LetterRequest(app core.App, engine *templating.Engine, e *c rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series) if err != nil { - return err + return Error404(e, engine, err) } data["entries"] = bmap data["relations"] = rmap @@ -121,14 +114,15 @@ func (p *ReihenPage) PersonRequest(app core.App, engine *templating.Engine, e *c agent, err := dbmodels.AgentForId(app, person) if err != nil { - return err + return Error404(e, engine, err) } data["a"] = agent series, relations, entries, err := dbmodels.SeriesForAgent(app, person) if err != nil { - return err + return Error404(e, engine, err) } + dbmodels.SortSeriessesByTitle(series) data["series"] = series data["relations"] = relations data["entries"] = entries @@ -143,13 +137,13 @@ func (p *ReihenPage) PlaceRequest(app core.App, engine *templating.Engine, e *co pl, err := dbmodels.PlaceForId(app, place) if err != nil { - return err + return Error404(e, engine, err) } data["p"] = pl series, relations, entries, err := dbmodels.SeriesForPlace(app, place) if err != nil { - return err + return Error404(e, engine, err) } data["series"] = series data["relations"] = relations @@ -164,7 +158,7 @@ func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *c data[PARAM_SEARCH] = search series, altseries, err := dbmodels.BasicSearchSeries(app, search) if err != nil { - return err + return Error404(e, engine, err) } dbmodels.SortSeriessesByTitle(series) dbmodels.SortSeriessesByTitle(altseries) @@ -173,7 +167,7 @@ func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *c rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series) if err != nil { - return err + return Error404(e, engine, err) } data["entries"] = bmap data["relations"] = rmap @@ -213,7 +207,7 @@ func (p *ReihenPage) CommonData(app core.App, data map[string]interface{}) error func (p *ReihenPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error { err := p.CommonData(request.App, data) if err != nil { - return err + return Error404(request, engine, err) } var builder strings.Builder diff --git a/scratchpad.md b/scratchpad.md index 424c7a1..f857db9 100644 --- a/scratchpad.md +++ b/scratchpad.md @@ -21,3 +21,9 @@ Für einen Umzug: Alle PB-Abfragen die Record benutzen, nach sql-Abfragen umwandeln. Eigene DB-Connection Modelle umwandeln (zzt RecordProxy) + + +- Abfragen Personen +- Abfragen Person +- Ersellen & Abfragen FTS5-Tabellen +- Erstellen Textseiten diff --git a/templating/engine.go b/templating/engine.go index ed0ffb2..ab13679 100644 --- a/templating/engine.go +++ b/templating/engine.go @@ -44,6 +44,7 @@ func (e *Engine) funcs() error { e.mu.Lock() e.mu.Unlock() e.AddFunc("Safe", functions.Safe) + e.AddFunc("Arr", functions.Arr) return nil } @@ -101,6 +102,10 @@ func (e *Engine) AddFuncs(funcs map[string]interface{}) { func (e *Engine) Render(out io.Writer, path string, ld map[string]interface{}, layout ...string) error { gd := e.GlobalData + if ld == nil { + ld = make(map[string]interface{}) + } + // INFO: don't pollute the global data space for k, v := range gd { _, ok := ld[k] diff --git a/views/assets/style.css b/views/assets/style.css index 9e6a7c0..c21a236 100644 --- a/views/assets/style.css +++ b/views/assets/style.css @@ -1 +1 @@ -/*! tailwindcss v4.0.5 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:"Source Sans 3","Merriweather Sans",ui-sans-serif;--font-serif:"Merriweather",ui-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(.637 .237 25.331);--color-slate-50:oklch(.984 .003 247.858);--color-slate-700:oklch(.372 .044 257.287);--color-slate-900:oklch(.208 .042 265.755);--color-gray-200:oklch(.928 .006 264.531);--spacing:.25rem;--breakpoint-2xl:96rem;--font-weight-bold:700;--ease-in:cubic-bezier(.4,0,1,1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components{html{font-size:15.5px}body{background-color:var(--color-slate-50)}h1,h2,h3,h4{font-family:var(--font-serif);--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}a{-webkit-hyphens:none;hyphens:none;color:var(--color-slate-700);text-decoration-line:underline;text-decoration-style:dotted}@media (hover:hover){a:hover{color:var(--color-slate-900);text-decoration-style:solid}}ul{margin-block:calc(var(--spacing)*2)}li{margin-left:calc(var(--spacing)*14);list-style-type:disc}a[aria-current=page]{color:var(--color-red-500)!important}main{flex-grow:1;flex-shrink:0}}@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-\(--breakpoint-2xl\){max-width:var(--breakpoint-2xl)}.translate-2{--tw-translate-x:calc(var(--spacing)*2);--tw-translate-y:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.justify-center{justify-content:center}.align-bottom{vertical-align:bottom}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-wrap{text-wrap:wrap}.italic{font-style:italic}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.\[a-zA-Z\:\\-\\\.\]{a-zA-Z:\-\.}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false} +/*! tailwindcss v4.0.5 | MIT License | https://tailwindcss.com */@layer theme{:root,:host{--font-sans:"Source Sans 3","Merriweather Sans",ui-sans-serif;--font-serif:"Merriweather",ui-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(.637 .237 25.331);--color-slate-50:oklch(.984 .003 247.858);--color-slate-700:oklch(.372 .044 257.287);--color-slate-900:oklch(.208 .042 265.755);--color-gray-200:oklch(.928 .006 264.531);--spacing:.25rem;--breakpoint-2xl:96rem;--font-weight-bold:700;--ease-in:cubic-bezier(.4,0,1,1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-font-feature-settings:var(--font-sans--font-feature-settings);--default-font-variation-settings:var(--font-sans--font-variation-settings);--default-mono-font-family:var(--font-mono);--default-mono-font-feature-settings:var(--font-mono--font-feature-settings);--default-mono-font-variation-settings:var(--font-mono--font-variation-settings)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1;color:color-mix(in oklab,currentColor 50%,transparent)}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}}@layer components{html{font-size:15.5px}body{background-color:var(--color-slate-50)}h1,h2,h3,h4{font-family:var(--font-serif);--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}a{-webkit-hyphens:none;hyphens:none;color:var(--color-slate-700);text-decoration-line:underline;text-decoration-style:dotted}@media (hover:hover){a:hover{color:var(--color-slate-900);text-decoration-style:solid}}ul{margin-block:calc(var(--spacing)*2)}li{margin-left:calc(var(--spacing)*14);list-style-type:disc}a[aria-current=page]{color:var(--color-red-500)!important}main{flex-grow:1;flex-shrink:0}}@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-12{margin-top:calc(var(--spacing)*12)}.mb-1\.5{margin-bottom:calc(var(--spacing)*1.5)}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-1{height:calc(var(--spacing)*1)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-\(--breakpoint-2xl\){max-width:var(--breakpoint-2xl)}.translate-2{--tw-translate-x:calc(var(--spacing)*2);--tw-translate-y:calc(var(--spacing)*2);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.justify-center{justify-content:center}.gap-x-2{column-gap:calc(var(--spacing)*2)}.align-bottom{vertical-align:bottom}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-wrap{text-wrap:wrap}.italic{font-style:italic}.overline{text-decoration-line:overline}.underline{text-decoration-line:underline}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in{--tw-ease:var(--ease-in);transition-timing-function:var(--ease-in)}.\[a-zA-Z\:\\-\\\.\]{a-zA-Z:\-\.}.\[\&_td\]\:\!align-top td{vertical-align:top!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false} diff --git a/views/layouts/components/_menu.gohtml b/views/layouts/components/_menu.gohtml index 7e0efa4..5c83481 100644 --- a/views/layouts/components/_menu.gohtml +++ b/views/layouts/components/_menu.gohtml @@ -1 +1,4 @@ -
+ diff --git a/views/routes/almanach/body.gohtml b/views/routes/almanach/body.gohtml new file mode 100644 index 0000000..50674ba --- /dev/null +++ b/views/routes/almanach/body.gohtml @@ -0,0 +1,3 @@ +{{ $model := . }} + +{{ $model.entry.TitleStmt }} diff --git a/views/routes/almanach/head.gohtml b/views/routes/almanach/head.gohtml new file mode 100644 index 0000000..9b9c1dc --- /dev/null +++ b/views/routes/almanach/head.gohtml @@ -0,0 +1 @@ +{{ .Error }}
+{{ end }} diff --git a/views/routes/errors/head.gohtml b/views/routes/errors/head.gohtml new file mode 100644 index 0000000..e69de29 diff --git a/views/routes/person/body.gohtml b/views/routes/person/body.gohtml new file mode 100644 index 0000000..624b9f7 --- /dev/null +++ b/views/routes/person/body.gohtml @@ -0,0 +1,22 @@ +{{ $model := . }} + +{{ if .entries }} +|
+
+ {{ $agent.Name }}
+ {{ if $agent.Pseudonyms }}
+ + ({{ $agent.Pseudonyms }}) + {{ end }} + + |
+ + {{ if $agent.CorporateBody }} + Körperschaft + {{ else }} + {{ $agent.Profession }}, + {{ $agent.BiographicalData }} + {{ end }} + | +{{ $agent.References }} | +
|
+ {{ $agent.Name }}
+ {{ if $agent.Pseudonyms }}
+ + ({{ $agent.Pseudonyms }}) + {{ end }} + |
+ + {{ if $agent.CorporateBody }} + Körperschaft + {{ else }} + {{ $agent.Profession }}, + {{ $agent.BiographicalData }} + {{ end }} + | +{{ $agent.References }} | +
Keine Personen gefunden.
+ {{ end }} +