mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
Bandsuche
This commit is contained in:
@@ -31,6 +31,15 @@ func REntriesAgents_Entry(app core.App, id string) ([]*REntriesAgents, error) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func REntriesAgents_Entries(app core.App, ids []any) ([]*REntriesAgents, error) {
|
||||||
|
return TableByFields[[]*REntriesAgents](
|
||||||
|
app,
|
||||||
|
RelationTableName(ENTRIES_TABLE, AGENTS_TABLE),
|
||||||
|
ENTRIES_TABLE,
|
||||||
|
ids,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func RContentsAgents_Agent(app core.App, id string) ([]*RContentsAgents, error) {
|
func RContentsAgents_Agent(app core.App, id string) ([]*RContentsAgents, error) {
|
||||||
return TableByFields[[]*RContentsAgents](
|
return TableByFields[[]*RContentsAgents](
|
||||||
app,
|
app,
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ func ReplaceSlashParen(s string) string {
|
|||||||
return strings.ReplaceAll(s, "/)", "<p>")
|
return strings.ReplaceAll(s, "/)", "<p>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReplaceSlashParenSlash(s string) string {
|
||||||
|
return strings.ReplaceAll(s, "/)", "/")
|
||||||
|
}
|
||||||
|
|
||||||
func Lower(s string) string {
|
func Lower(s string) string {
|
||||||
return cases.Lower(language.German).String(s)
|
return cases.Lower(language.German).String(s)
|
||||||
}
|
}
|
||||||
|
|||||||
421
pages/suche.go
421
pages/suche.go
@@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/datatypes"
|
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
@@ -53,6 +52,15 @@ func (p *SuchePage) Setup(router *router.Router[*core.RequestEvent], app core.Ap
|
|||||||
return engine.Response404(e, err, nil)
|
return engine.Response404(e, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if paras.Query != "" {
|
||||||
|
switch paras.Collection {
|
||||||
|
case "baende":
|
||||||
|
return p.SimpleSearchBaendeRequest(app, engine, e, *paras)
|
||||||
|
case "beitraege":
|
||||||
|
return p.SimpleSearchReihenRequest(app, engine, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data := make(map[string]interface{})
|
data := make(map[string]interface{})
|
||||||
data["parameters"] = paras
|
data["parameters"] = paras
|
||||||
return engine.Response200(e, p.Template+paras.Collection+"/", data, p.Layout)
|
return engine.Response200(e, p.Template+paras.Collection+"/", data, p.Layout)
|
||||||
@@ -67,45 +75,19 @@ func (p *SuchePage) SimpleSearchReihenRequest(app core.App, engine *templating.E
|
|||||||
|
|
||||||
func (p *SuchePage) SimpleSearchBaendeRequest(app core.App, engine *templating.Engine, e *core.RequestEvent, pp Parameters) error {
|
func (p *SuchePage) SimpleSearchBaendeRequest(app core.App, engine *templating.Engine, e *core.RequestEvent, pp Parameters) error {
|
||||||
data := make(map[string]interface{})
|
data := make(map[string]interface{})
|
||||||
params, err := NewSimpleParameters(e, pp)
|
params, err := NewSearchParameters(e, pp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return engine.Response404(e, err, nil)
|
return engine.Response404(e, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
query := params.NormalizeQuery()
|
result, err := SimpleSearchBaende(app, *params)
|
||||||
if len(query) == 0 {
|
|
||||||
engine.Response404(e, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
fields := params.FieldSetBaende()
|
|
||||||
if len(fields) == 0 {
|
|
||||||
return engine.Response404(e, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
ids, err := dbmodels.FTS5Search(app, dbmodels.ENTRIES_TABLE, dbmodels.FTS5QueryRequest{
|
|
||||||
Fields: fields,
|
|
||||||
Query: query,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return engine.Response500(e, err, nil)
|
return engine.Response404(e, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
idsany := datatypes.ToAny(ids)
|
data["parameters"] = params
|
||||||
entries, err := dbmodels.Entries_IDs(app, idsany)
|
data["result"] = result
|
||||||
if err != nil {
|
return engine.Response200(e, p.Template+pp.Collection+"/", data, p.Layout)
|
||||||
return engine.Response500(e, err, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbmodels.Sort_Entries_Title_Year(entries)
|
|
||||||
data["entries"] = entries
|
|
||||||
data["count"] = len(entries)
|
|
||||||
|
|
||||||
eids := []any{}
|
|
||||||
for _, entry := range entries {
|
|
||||||
eids = append(eids, entry.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine.Response404(e, nil, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -128,7 +110,7 @@ const (
|
|||||||
BAENDE_PARAM_TITLE = "title"
|
BAENDE_PARAM_TITLE = "title"
|
||||||
BAENDE_PARAM_SERIES = "series"
|
BAENDE_PARAM_SERIES = "series"
|
||||||
BAENDE_PARAM_PERSONS = "persons"
|
BAENDE_PARAM_PERSONS = "persons"
|
||||||
BAENDE_PARAM_PLACES = "pubdata"
|
BAENDE_PARAM_PLACES = "places"
|
||||||
BAENDE_PARAM_REFS = "references"
|
BAENDE_PARAM_REFS = "references"
|
||||||
BAENDE_PARAM_ANNOTATIONS = "annotations"
|
BAENDE_PARAM_ANNOTATIONS = "annotations"
|
||||||
BAENDE_PARAM_YEAR = "year"
|
BAENDE_PARAM_YEAR = "year"
|
||||||
@@ -169,8 +151,10 @@ func (p *Parameters) NormalizeQuery() []string {
|
|||||||
return dbmodels.NormalizeQuery(p.Query)
|
return dbmodels.NormalizeQuery(p.Query)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimpleParameters struct {
|
type SearchParameters struct {
|
||||||
Parameters
|
Parameters
|
||||||
|
Sort string
|
||||||
|
|
||||||
Annotations bool
|
Annotations bool
|
||||||
Persons bool
|
Persons bool
|
||||||
Title bool
|
Title bool
|
||||||
@@ -179,9 +163,20 @@ type SimpleParameters struct {
|
|||||||
Places bool
|
Places bool
|
||||||
Refs bool
|
Refs bool
|
||||||
Year bool
|
Year bool
|
||||||
|
|
||||||
|
AnnotationsString string
|
||||||
|
PersonsString string
|
||||||
|
TitleString string
|
||||||
|
AlmString string
|
||||||
|
SeriesString string
|
||||||
|
PlacesString string
|
||||||
|
RefsString string
|
||||||
|
YearString string
|
||||||
|
|
||||||
|
TypeFilter string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSimpleParameters(e *core.RequestEvent, p Parameters) (*SimpleParameters, error) {
|
func NewSearchParameters(e *core.RequestEvent, p Parameters) (*SearchParameters, error) {
|
||||||
q := e.Request.URL.Query().Get(PARAM_QUERY)
|
q := e.Request.URL.Query().Get(PARAM_QUERY)
|
||||||
if q == "" {
|
if q == "" {
|
||||||
return nil, ErrNoQuery
|
return nil, ErrNoQuery
|
||||||
@@ -196,10 +191,14 @@ func NewSimpleParameters(e *core.RequestEvent, p Parameters) (*SimpleParameters,
|
|||||||
annotations := e.Request.URL.Query().Get(BAENDE_PARAM_ANNOTATIONS) == "on"
|
annotations := e.Request.URL.Query().Get(BAENDE_PARAM_ANNOTATIONS) == "on"
|
||||||
year := e.Request.URL.Query().Get(BAENDE_PARAM_YEAR) == "on"
|
year := e.Request.URL.Query().Get(BAENDE_PARAM_YEAR) == "on"
|
||||||
|
|
||||||
// TODO: sanity check here if any single field is selected
|
sort := e.Request.URL.Query().Get("sort")
|
||||||
|
if sort == "" {
|
||||||
|
sort = "year"
|
||||||
|
}
|
||||||
|
|
||||||
return &SimpleParameters{
|
return &SearchParameters{
|
||||||
Parameters: p,
|
Parameters: p,
|
||||||
|
Sort: sort,
|
||||||
// INFO: Common parameters
|
// INFO: Common parameters
|
||||||
Alm: alm,
|
Alm: alm,
|
||||||
Title: title,
|
Title: title,
|
||||||
@@ -214,37 +213,319 @@ func NewSimpleParameters(e *core.RequestEvent, p Parameters) (*SimpleParameters,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p SimpleParameters) FieldSetBaende() []string {
|
func (p SearchParameters) ToQueryParams() string {
|
||||||
fields := []string{}
|
if !p.Extended {
|
||||||
if p.Alm {
|
q := fmt.Sprintf("?q=%s", p.Query)
|
||||||
fields = append(fields, dbmodels.MUSENALMID_FIELD)
|
if p.Alm {
|
||||||
|
q += "&alm=on"
|
||||||
|
}
|
||||||
|
if p.Title {
|
||||||
|
q += "&title=on"
|
||||||
|
}
|
||||||
|
if p.Persons {
|
||||||
|
q += "&persons=on"
|
||||||
|
}
|
||||||
|
if p.Annotations {
|
||||||
|
q += "&annotations=on"
|
||||||
|
}
|
||||||
|
if p.Series {
|
||||||
|
q += "&series=on"
|
||||||
|
}
|
||||||
|
if p.Places {
|
||||||
|
q += "&places=on"
|
||||||
|
}
|
||||||
|
if p.Refs {
|
||||||
|
q += "&references=on"
|
||||||
|
}
|
||||||
|
if p.Year {
|
||||||
|
q += "&year=on"
|
||||||
|
}
|
||||||
|
return q
|
||||||
}
|
}
|
||||||
if p.Title {
|
return ""
|
||||||
fields = append(fields,
|
}
|
||||||
dbmodels.TITLE_STMT_FIELD,
|
|
||||||
dbmodels.SUBTITLE_STMT_FIELD,
|
func (p SearchParameters) IsBeandeSearch() bool {
|
||||||
dbmodels.INCIPIT_STMT_FIELD,
|
return p.Collection == "baende" && (p.Query != "" || (p.AnnotationsString != "" || p.PersonsString != "" || p.TitleString != "" || p.AlmString != "" || p.SeriesString != "" || p.PlacesString != "" || p.RefsString != "" || p.YearString != ""))
|
||||||
dbmodels.VARIANT_TITLE_FIELD,
|
}
|
||||||
dbmodels.PARALLEL_TITLE_FIELD,
|
|
||||||
)
|
func (p SearchParameters) FieldSetBaende() []dbmodels.FTS5QueryRequest {
|
||||||
}
|
ret := []dbmodels.FTS5QueryRequest{}
|
||||||
if p.Series {
|
if p.Query != "" {
|
||||||
fields = append(fields, dbmodels.SERIES_TABLE)
|
fields := []string{dbmodels.ID_FIELD}
|
||||||
}
|
if p.Alm {
|
||||||
if p.Persons {
|
fields = append(fields, dbmodels.MUSENALMID_FIELD)
|
||||||
fields = append(fields, dbmodels.RESPONSIBILITY_STMT_FIELD, dbmodels.AGENTS_TABLE)
|
}
|
||||||
}
|
if p.Title {
|
||||||
if p.Places {
|
// INFO: Preferred Title is not here to avoid hitting the Reihentitel
|
||||||
fields = append(fields, dbmodels.PLACE_STMT_FIELD, dbmodels.PLACES_TABLE, dbmodels.PUBLICATION_STMT_FIELD)
|
fields = append(fields,
|
||||||
}
|
dbmodels.TITLE_STMT_FIELD,
|
||||||
if p.Refs {
|
dbmodels.SUBTITLE_STMT_FIELD,
|
||||||
fields = append(fields, dbmodels.REFERENCES_FIELD)
|
dbmodels.INCIPIT_STMT_FIELD,
|
||||||
}
|
dbmodels.VARIANT_TITLE_FIELD,
|
||||||
if p.Annotations {
|
dbmodels.PARALLEL_TITLE_FIELD,
|
||||||
fields = append(fields, dbmodels.ANNOTATION_FIELD)
|
)
|
||||||
}
|
}
|
||||||
if p.Year {
|
if p.Series {
|
||||||
fields = append(fields, dbmodels.YEAR_FIELD)
|
fields = append(fields, dbmodels.SERIES_TABLE)
|
||||||
}
|
}
|
||||||
return fields
|
if p.Persons {
|
||||||
|
fields = append(fields, dbmodels.RESPONSIBILITY_STMT_FIELD, dbmodels.AGENTS_TABLE)
|
||||||
|
}
|
||||||
|
if p.Places {
|
||||||
|
fields = append(fields, dbmodels.PLACES_TABLE, dbmodels.PLACE_STMT_FIELD)
|
||||||
|
}
|
||||||
|
if p.Refs {
|
||||||
|
fields = append(fields, dbmodels.REFERENCES_FIELD)
|
||||||
|
}
|
||||||
|
if p.Annotations {
|
||||||
|
fields = append(fields, dbmodels.ANNOTATION_FIELD)
|
||||||
|
}
|
||||||
|
if p.Year {
|
||||||
|
fields = append(fields, dbmodels.YEAR_FIELD)
|
||||||
|
}
|
||||||
|
|
||||||
|
que := p.NormalizeQuery()
|
||||||
|
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: fields,
|
||||||
|
Query: p.NormalizeQuery(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.IsExtendedSearch() {
|
||||||
|
if p.AnnotationsString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.AnnotationsString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.ANNOTATION_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.PersonsString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.PersonsString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.AGENTS_TABLE, dbmodels.RESPONSIBILITY_STMT_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.TitleString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.TitleString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.TITLE_STMT_FIELD, dbmodels.SUBTITLE_STMT_FIELD, dbmodels.INCIPIT_STMT_FIELD, dbmodels.VARIANT_TITLE_FIELD, dbmodels.PARALLEL_TITLE_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.AlmString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.AlmString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.MUSENALMID_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.SeriesString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.SeriesString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.SERIES_TABLE},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.PlacesString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.PlacesString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.PLACES_TABLE, dbmodels.PLACE_STMT_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.RefsString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.RefsString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.REFERENCES_FIELD},
|
||||||
|
Query: que,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.YearString != "" {
|
||||||
|
que := dbmodels.NormalizeQuery(p.YearString)
|
||||||
|
if len(que) > 0 {
|
||||||
|
ret = append(ret, dbmodels.FTS5QueryRequest{
|
||||||
|
Fields: []string{dbmodels.YEAR_FIELD},
|
||||||
|
Query: dbmodels.NormalizeQuery(p.YearString),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SearchParameters) IsExtendedSearch() bool {
|
||||||
|
return p.AnnotationsString != "" || p.PersonsString != "" || p.TitleString != "" || p.AlmString != "" || p.SeriesString != "" || p.PlacesString != "" || p.RefsString != "" || p.YearString != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p SearchParameters) NormalizeQuery() []string {
|
||||||
|
return dbmodels.NormalizeQuery(p.Query)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SearchResultBaende struct {
|
||||||
|
// these are the sorted IDs for hits
|
||||||
|
Hits []string
|
||||||
|
Series map[string]*dbmodels.Series // <- Key: Series ID
|
||||||
|
Entries map[string]*dbmodels.Entry // <- Key: Entry ID
|
||||||
|
Places map[string]*dbmodels.Place // <- All places, Key: Place IDs
|
||||||
|
Agents map[string]*dbmodels.Agent // <- Key: Agent IDs
|
||||||
|
|
||||||
|
// INFO: this is as they say doppelt gemoppelt bc of a logic error i made while tired
|
||||||
|
EntriesSeries map[string][]*dbmodels.REntriesSeries // <- Key: Entry ID
|
||||||
|
SeriesEntries map[string][]*dbmodels.REntriesSeries // <- Key: Series ID
|
||||||
|
EntriesAgents map[string][]*dbmodels.REntriesAgents // <- Key: Entry ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func SimpleSearchBaende(app core.App, params SearchParameters) (*SearchResultBaende, error) {
|
||||||
|
fields := params.FieldSetBaende()
|
||||||
|
if len(fields) == 0 {
|
||||||
|
return nil, ErrNoQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
ids, err := dbmodels.FTS5Search(app, dbmodels.ENTRIES_TABLE, fields...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resultids := []any{}
|
||||||
|
for _, id := range ids {
|
||||||
|
resultids = append(resultids, id.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
entries, err := dbmodels.Entries_IDs(app, resultids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
entriesmap := make(map[string]*dbmodels.Entry)
|
||||||
|
for _, entry := range entries {
|
||||||
|
entriesmap[entry.Id] = entry
|
||||||
|
}
|
||||||
|
|
||||||
|
series, relations, err := Series_Entries(app, entries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
seriesmap := make(map[string]*dbmodels.Series)
|
||||||
|
for _, s := range series {
|
||||||
|
seriesmap[s.Id] = s
|
||||||
|
}
|
||||||
|
|
||||||
|
relationsmap := make(map[string][]*dbmodels.REntriesSeries)
|
||||||
|
invrelationsmap := make(map[string][]*dbmodels.REntriesSeries)
|
||||||
|
for _, r := range relations {
|
||||||
|
invrelationsmap[r.Series()] = append(invrelationsmap[r.Series()], r)
|
||||||
|
relationsmap[r.Entry()] = append(relationsmap[r.Entry()], r)
|
||||||
|
}
|
||||||
|
|
||||||
|
agents, arelations, err := Agents_Entries_IDs(app, resultids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
agentsmap := make(map[string]*dbmodels.Agent)
|
||||||
|
for _, a := range agents {
|
||||||
|
agentsmap[a.Id] = a
|
||||||
|
}
|
||||||
|
|
||||||
|
relationsagentsmap := make(map[string][]*dbmodels.REntriesAgents)
|
||||||
|
for _, r := range arelations {
|
||||||
|
relationsagentsmap[r.Entry()] = append(relationsagentsmap[r.Entry()], r)
|
||||||
|
}
|
||||||
|
|
||||||
|
placesids := []any{}
|
||||||
|
for _, entry := range entries {
|
||||||
|
for _, place := range entry.Places() {
|
||||||
|
placesids = append(placesids, place)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
places, err := dbmodels.Places_IDs(app, placesids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
placesmap := make(map[string]*dbmodels.Place)
|
||||||
|
for _, place := range places {
|
||||||
|
placesmap[place.Id] = place
|
||||||
|
}
|
||||||
|
|
||||||
|
hits := []string{}
|
||||||
|
if params.Sort == "series" {
|
||||||
|
dbmodels.Sort_Series_Title(series)
|
||||||
|
for _, s := range series {
|
||||||
|
hits = append(hits, s.Id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dbmodels.Sort_Entries_Year_Title(entries)
|
||||||
|
for _, e := range entries {
|
||||||
|
hits = append(hits, e.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SearchResultBaende{
|
||||||
|
Hits: hits,
|
||||||
|
Series: seriesmap,
|
||||||
|
Entries: entriesmap,
|
||||||
|
Places: placesmap,
|
||||||
|
Agents: agentsmap,
|
||||||
|
EntriesSeries: relationsmap,
|
||||||
|
SeriesEntries: invrelationsmap,
|
||||||
|
EntriesAgents: relationsagentsmap,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r SearchResultBaende) Count() int {
|
||||||
|
return len(r.Entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r SearchResultBaende) SeriesCount() int {
|
||||||
|
return len(r.Series)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Agents_Entries_IDs(app core.App, ids []any) ([]*dbmodels.Agent, []*dbmodels.REntriesAgents, error) {
|
||||||
|
relations, err := dbmodels.REntriesAgents_Entries(app, ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
agentids := []any{}
|
||||||
|
for _, r := range relations {
|
||||||
|
agentids = append(agentids, r.Agent())
|
||||||
|
}
|
||||||
|
|
||||||
|
agents, err := dbmodels.Agents_IDs(app, agentids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return agents, relations, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ func (e *Engine) funcs() error {
|
|||||||
e.AddFunc("Upper", functions.Upper)
|
e.AddFunc("Upper", functions.Upper)
|
||||||
e.AddFunc("First", functions.First)
|
e.AddFunc("First", functions.First)
|
||||||
e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
|
e.AddFunc("ReplaceSlashParen", functions.ReplaceSlashParen)
|
||||||
|
e.AddFunc("ReplaceSlashParenSlash", functions.ReplaceSlashParenSlash)
|
||||||
|
|
||||||
// Time & Date Functions
|
// Time & Date Functions
|
||||||
e.AddFunc("Today", functions.Today)
|
e.AddFunc("Today", functions.Today)
|
||||||
@@ -263,7 +264,7 @@ func (e *Engine) Response404(request *core.RequestEvent, err error, data map[str
|
|||||||
data["page"] = requestData(request)
|
data["page"] = requestData(request)
|
||||||
|
|
||||||
err2 := e.Render(&sb, "/errors/404/", data)
|
err2 := e.Render(&sb, "/errors/404/", data)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
return e.Response500(request, errors.Join(err, err2), data)
|
return e.Response500(request, errors.Join(err, err2), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,17 @@
|
|||||||
<link href="/assets/css/remixicon.css" rel="stylesheet" />
|
<link href="/assets/css/remixicon.css" rel="stylesheet" />
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/css/fonts.css" />
|
<link rel="stylesheet" type="text/css" href="/assets/css/fonts.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
document.body.addEventListener("htmx:responseError", function (event) {
|
||||||
|
const config = event.detail.requestConfig;
|
||||||
|
if (config.boosted) {
|
||||||
|
document.body.innerHTML = event.detail.xhr.responseText;
|
||||||
|
const newUrl = event.detail.xhr.responseURL || config.url;
|
||||||
|
window.history.pushState(null, "", newUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="w-full text-lg" hx-ext="response-targets" hx-boost="true">
|
<body class="w-full text-lg" hx-ext="response-targets" hx-boost="true">
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
{{ $model := . }}
|
{{ $model := . }}
|
||||||
{{/* .parameters
|
{{/* .parameters
|
||||||
type Parameters struct {
|
type SearchParameters struct {
|
||||||
Extended bool
|
|
||||||
Collection string
|
|
||||||
Query string
|
|
||||||
}
|
|
||||||
type SimpleParameters struct {
|
|
||||||
Parameters
|
Parameters
|
||||||
|
Sort string
|
||||||
|
|
||||||
Annotations bool
|
Annotations bool
|
||||||
Persons bool
|
Persons bool
|
||||||
Title bool
|
Title bool
|
||||||
@@ -15,9 +12,61 @@
|
|||||||
Places bool
|
Places bool
|
||||||
Refs bool
|
Refs bool
|
||||||
Year bool
|
Year bool
|
||||||
|
|
||||||
|
AnnotationsString string
|
||||||
|
PersonsString string
|
||||||
|
TitleString string
|
||||||
|
AlmString string
|
||||||
|
SeriesString string
|
||||||
|
PlacesString string
|
||||||
|
RefsString string
|
||||||
|
YearString string
|
||||||
|
|
||||||
|
TypeFilter string
|
||||||
|
}
|
||||||
|
type Parameters struct {
|
||||||
|
Query string
|
||||||
|
Collection string
|
||||||
|
Extended bool
|
||||||
|
}
|
||||||
|
type SearchResultBaende struct {
|
||||||
|
// these are the sorted IDs for hits
|
||||||
|
Hits []string
|
||||||
|
Series map[string]*dbmodels.Series // <- Key: Series ID
|
||||||
|
Entries map[string]*dbmodels.Entry // <- Key: Entry ID
|
||||||
|
Places map[string]*dbmodels.Place // <- All places, Key: Place IDs
|
||||||
|
Agents map[string]*dbmodels.Agent // <- Key: Agent IDs
|
||||||
|
|
||||||
|
EntriesSeries map[string][]*dbmodels.REntriesSeries // <- Key: Whatever the Hit IDs are
|
||||||
|
SeriesEntries map[string][]*dbmodels.REntriesSeries // <- Key: Whatever the Hit IDs are
|
||||||
|
EntriesAgents map[string][]*dbmodels.REntriesAgents // <- Key: Entry ID
|
||||||
}
|
}
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
|
{{ $isAlm := false }}
|
||||||
|
{{ $isTitle := false }}
|
||||||
|
{{ $isRefs := false }}
|
||||||
|
{{ $isPlaces := false }}
|
||||||
|
{{ $isYear := false }}
|
||||||
|
{{ $isSeries := false }}
|
||||||
|
{{ $isPersons := false }}
|
||||||
|
{{ $isAnnotations := false }}
|
||||||
|
|
||||||
|
{{ if $model.parameters.Query }}
|
||||||
|
{{- $isAlm = or $model.parameters.Alm $model.parameters.AlmString -}}
|
||||||
|
{{- $isTitle = or $model.parameters.Title $model.parameters.TitleString -}}
|
||||||
|
{{- $isRefs = or $model.parameters.Refs $model.parameters.RefsString -}}
|
||||||
|
{{- $isPlaces = or $model.parameters.Places $model.parameters.PlacesString -}}
|
||||||
|
{{- $isYear = or $model.parameters.Year $model.parameters.YearString -}}
|
||||||
|
{{- $isSeries = or $model.parameters.Series $model.parameters.SeriesString -}}
|
||||||
|
{{- $isPersons = or $model.parameters.Persons $model.parameters.PersonsString -}}
|
||||||
|
{{- $isAnnotations = or $model.parameters.Annotations $model.parameters.AnnotationsString -}}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- $isBase := not (or $isAlm $isTitle $isRefs $isPlaces $isYear $isSeries $isPersons
|
||||||
|
$isAnnotations)
|
||||||
|
-}}
|
||||||
|
|
||||||
|
|
||||||
<div id="searchcontrol" class="container-normal">
|
<div id="searchcontrol" class="container-normal">
|
||||||
{{- template "_heading" $model.parameters -}}
|
{{- template "_heading" $model.parameters -}}
|
||||||
@@ -37,35 +86,79 @@
|
|||||||
{{ template "_searchboxsimple" Arr $model.parameters true $q }}
|
{{ template "_searchboxsimple" Arr $model.parameters true $q }}
|
||||||
<fieldset class="selectgroup">
|
<fieldset class="selectgroup">
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="alm" id="alm" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="alm"
|
||||||
|
id="alm"
|
||||||
|
{{ if or $isBase $isAlm -}}checked{{- end -}} />
|
||||||
<label for="alm">Almanach-Nr.</label>
|
<label for="alm">Almanach-Nr.</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="title" id="title" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="title"
|
||||||
|
id="title"
|
||||||
|
{{ if or $isBase $isTitle -}}checked{{- end -}} />
|
||||||
<label for="title">Titel</label>
|
<label for="title">Titel</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="series" id="series" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="series"
|
||||||
|
id="series"
|
||||||
|
{{ if or $isBase $isSeries -}}checked{{- end -}} />
|
||||||
<label for="series">Reihentitel</label>
|
<label for="series">Reihentitel</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="persons" id="persons" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="persons"
|
||||||
|
id="persons"
|
||||||
|
{{ if or $isBase
|
||||||
|
$isPersons
|
||||||
|
-}}
|
||||||
|
checked
|
||||||
|
{{- end -}} />
|
||||||
<label for="persons">Personen & Verlage</label>
|
<label for="persons">Personen & Verlage</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="pubdata" id="pubdata" checked />
|
<input
|
||||||
<label for="pubdata">Orte</label>
|
type="checkbox"
|
||||||
|
name="places"
|
||||||
|
id="places"
|
||||||
|
{{ if or $isBase $isPlaces -}}checked{{- end -}} />
|
||||||
|
<label for="places">Orte</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="year" id="year" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="year"
|
||||||
|
id="year"
|
||||||
|
{{ if or $isBase $isYear -}}checked{{- end -}} />
|
||||||
<label for="year">Jahr</label>
|
<label for="year">Jahr</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="references" id="references" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="references"
|
||||||
|
id="references"
|
||||||
|
{{ if or $isBase
|
||||||
|
$isRefs
|
||||||
|
-}}
|
||||||
|
checked
|
||||||
|
{{- end -}} />
|
||||||
<label for="references">Nachweise</label>
|
<label for="references">Nachweise</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="selectgroup-option">
|
<div class="selectgroup-option">
|
||||||
<input type="checkbox" name="annotations" id="annotations" checked />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="annotations"
|
||||||
|
id="annotations"
|
||||||
|
{{ if or $isBase
|
||||||
|
$isAnnotations
|
||||||
|
-}}
|
||||||
|
checked
|
||||||
|
{{- end -}} />
|
||||||
<label for="annotations">Anmerkungen</label>
|
<label for="annotations">Anmerkungen</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -77,3 +170,94 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{- template "_fieldscript" -}}
|
{{- template "_fieldscript" -}}
|
||||||
|
|
||||||
|
{{- if $model.parameters.Query -}}
|
||||||
|
<div class="container-normal" id="searchresults">
|
||||||
|
<div class="border-b border-zinc-300 flex flex-row justify-between">
|
||||||
|
<div>
|
||||||
|
Suche nach <b>»{{ $model.parameters.Query }}«</b> ·
|
||||||
|
<i class="ri-book-line"></i>
|
||||||
|
{{ if eq $model.result.Count 1 -}}
|
||||||
|
Ein Band
|
||||||
|
{{ else -}}
|
||||||
|
{{ $model.result.Count }} Bände
|
||||||
|
{{- end }}
|
||||||
|
in
|
||||||
|
{{ if eq ($model.result.Series | len) 1 -}}
|
||||||
|
einer Reihe
|
||||||
|
{{ else -}}
|
||||||
|
{{ $model.result.Series | len }} Reihen
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for="sort"
|
||||||
|
class="align-baseline h-min self-end pb-1 mr-2 text-sm font-sans
|
||||||
|
text-stone-700"
|
||||||
|
>Sortierung</label
|
||||||
|
>
|
||||||
|
|
||||||
|
{{/* INFO: We always redrect to letter = A bc some letters dont exist for other professions */}}
|
||||||
|
<select
|
||||||
|
class="h-min pb-1 border-b-4 border-zinc-300 px-1.5"
|
||||||
|
name="sort"
|
||||||
|
id="sort"
|
||||||
|
hx-get="{{- $model.parameters.ToQueryParams -}}"
|
||||||
|
trigger="change"
|
||||||
|
hx-push-url="true"
|
||||||
|
hx-select="main"
|
||||||
|
auto-complete="off"
|
||||||
|
hx-target="main">
|
||||||
|
<option
|
||||||
|
value="year"
|
||||||
|
{{ if eq $model.parameters.Sort "year" -}}
|
||||||
|
selected
|
||||||
|
{{- end -}}>
|
||||||
|
Erscheinungsjahr
|
||||||
|
</option>
|
||||||
|
<option value="series" {{ if eq $model.parameters.Sort "series" -}}selected{{- end -}}>
|
||||||
|
Reihentitel A-Z
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{- if $model.result.Hits -}}
|
||||||
|
{{- if eq .parameters.Sort "series" -}}
|
||||||
|
<div class="mt-4">
|
||||||
|
{{- range $_, $hit := $model.result.Hits -}}
|
||||||
|
{{- $series := index $model.result.Series $hit -}}
|
||||||
|
<div class="font-serif font-bold py-1 border border-zinc-300 px-3 mt-6">
|
||||||
|
<span class="text-base font-sans pr-2 border-zinc-300">Reihe</span>
|
||||||
|
<span class="pl-2">{{ $series.Title }}</span>
|
||||||
|
</div>
|
||||||
|
{{- range $_, $rel := index $model.result.SeriesEntries $hit -}}
|
||||||
|
{{- $entry := index $model.result.Entries $rel.Entry -}}
|
||||||
|
{{- template "band" (Arr $model $entry $series.Id) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- else -}}
|
||||||
|
{{- range $_, $hit := $model.result.Hits -}}
|
||||||
|
{{- $entry := index $model.result.Entries $hit -}}
|
||||||
|
{{- template "band" (Arr $model $entry false) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
let elements = document.querySelectorAll('.search-text');
|
||||||
|
let mark_instance = new Mark(elements);
|
||||||
|
// INFO: we wait a little bit before marking, to settle everything
|
||||||
|
setTimeout(() => {
|
||||||
|
mark_instance.mark('{{ $model.parameters.Query }}', {
|
||||||
|
"seperateWordSearch": true,
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{- if not $model.result.Hits -}}
|
||||||
|
Keine Bände gefunden.
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|||||||
192
views/routes/suche/baende/components/band.gohtml
Normal file
192
views/routes/suche/baende/components/band.gohtml
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
{{- $model := index . 0 -}}
|
||||||
|
{{- $entry := index . 1 -}}
|
||||||
|
{{- $series := index . 2 -}}
|
||||||
|
{{/* .parameters
|
||||||
|
type SearchParameters struct {
|
||||||
|
Parameters
|
||||||
|
Sort string
|
||||||
|
|
||||||
|
Annotations bool
|
||||||
|
Persons bool
|
||||||
|
Title bool
|
||||||
|
Alm bool
|
||||||
|
Series bool
|
||||||
|
Places bool
|
||||||
|
Refs bool
|
||||||
|
Year bool
|
||||||
|
|
||||||
|
AnnotationsString string
|
||||||
|
PersonsString string
|
||||||
|
TitleString string
|
||||||
|
AlmString string
|
||||||
|
SeriesString string
|
||||||
|
PlacesString string
|
||||||
|
RefsString string
|
||||||
|
YearString string
|
||||||
|
|
||||||
|
TypeFilter string
|
||||||
|
}
|
||||||
|
type Parameters struct {
|
||||||
|
Query string
|
||||||
|
Collection string
|
||||||
|
Extended bool
|
||||||
|
}
|
||||||
|
type SearchResultBaende struct {
|
||||||
|
// these are the sorted IDs for hits
|
||||||
|
Hits []string
|
||||||
|
Series map[string]*dbmodels.Series // <- Key: Series ID
|
||||||
|
Entries map[string]*dbmodels.Entry // <- Key: Entry ID
|
||||||
|
Places map[string]*dbmodels.Place // <- All places, Key: Place IDs
|
||||||
|
Agents map[string]*dbmodels.Agent // <- Key: Agent IDs
|
||||||
|
|
||||||
|
EntriesSeries map[string][]*dbmodels.REntriesSeries // <- Key: Whatever the Hit IDs are
|
||||||
|
EntriesAgents map[string][]*dbmodels.REntriesAgents // <- Key: Entry ID
|
||||||
|
}
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{- $isAlm := or $model.parameters.Alm $model.parameters.AlmString -}}
|
||||||
|
{{- $isTitle := or $model.parameters.Title $model.parameters.TitleString -}}
|
||||||
|
{{- $isRefs := or $model.parameters.Refs $model.parameters.RefsString -}}
|
||||||
|
{{- $isPlaces := or $model.parameters.Places $model.parameters.PlacesString -}}
|
||||||
|
{{- $isYear := or $model.parameters.Year $model.parameters.YearString -}}
|
||||||
|
{{- $isSeries := or $model.parameters.Series $model.parameters.SeriesString -}}
|
||||||
|
{{- $isPersons := or $model.parameters.Persons $model.parameters.PersonsString -}}
|
||||||
|
{{- $isAnnotations := or $model.parameters.Annotations $model.parameters.AnnotationsString -}}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex flex-row max-w-[60rem]">
|
||||||
|
<div class="w-32 grow-0 shrink-0 border-r border-zinc-300 pr-3 pt-4">
|
||||||
|
<div class="flex flex-col items-end pt-1">
|
||||||
|
<div class="flex flex-row gap-x-1">
|
||||||
|
<div class="inline-block ml-1 whitespace-nowrap">
|
||||||
|
{{- if not $entry.TitleStmt -}}
|
||||||
|
<tool-tip position="right">
|
||||||
|
<i class="ri-forbid-line"></i>
|
||||||
|
<div class="data-tip">Keine nähere Erfassung</div>
|
||||||
|
</tool-tip>
|
||||||
|
{{- else if eq $entry.EditState "Edited" -}}
|
||||||
|
<tool-tip position="right">
|
||||||
|
<i class="ri-checkbox-circle-line"></i>
|
||||||
|
<div class="data-tip">Mit erfassten Beiträgen</div>
|
||||||
|
</tool-tip>
|
||||||
|
{{- else -}}
|
||||||
|
<tool-tip position="right">
|
||||||
|
<i class="ri-information-line"></i>
|
||||||
|
<div class="data-tip">Mit genaueren Titelangaben</div>
|
||||||
|
</tool-tip>
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="px-2 font-sans font-bold text-sm bg-stone-100 py-0.5 w-max rounded
|
||||||
|
{{ if $isAlm }}search-text{{- end -}}">
|
||||||
|
<a
|
||||||
|
href="/almanach/{{ $entry.MusenalmID }}"
|
||||||
|
class="no-underline rounded bg-stone-100 px-1.5">
|
||||||
|
Alm
|
||||||
|
{{ $entry.MusenalmID -}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ if $entry.References }}
|
||||||
|
<div
|
||||||
|
class="text-sm font-sans px-2 py-1 bg-stone-100 mt-1.5
|
||||||
|
{{ if $isRefs -}}
|
||||||
|
search-text
|
||||||
|
{{- end -}}">
|
||||||
|
{{ $entry.References }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="font-serif ml-3 pt-4">
|
||||||
|
<div class="font-bold">
|
||||||
|
<a href="/almanach/{{ $entry.MusenalmID }}" class="no-underline rounded ">
|
||||||
|
{{- $entry.PreferredTitle -}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{- if $entry.TitleStmt -}}
|
||||||
|
<div class="italic {{ if $isTitle -}}search-text{{- end -}}">{{- $entry.TitleStmt -}}</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if and $entry.ResponsibilityStmt (not (eq $entry.ResponsibilityStmt "unbezeichnet")) -}}
|
||||||
|
<div class="italic {{ if $isPersons -}}search-text{{- end -}}">
|
||||||
|
{{ $entry.ResponsibilityStmt -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
<div class="">
|
||||||
|
{{- if $entry.Places -}}
|
||||||
|
{{- range $_, $placeid := $entry.Places -}}
|
||||||
|
{{- $place := index $model.result.Places $placeid -}}
|
||||||
|
{{- if $place -}}
|
||||||
|
<div class="inline pr-1 {{ if $isPlaces -}}search-text{{- end -}}">
|
||||||
|
<a href="/reihen?place={{ $place.Id }}&hidden=true">{{ $place.Name }}</a>,
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
<a href="/reihen/?year={{ $entry.Year }}&hidden=true">
|
||||||
|
{{- if $entry.Year -}}
|
||||||
|
<div class="inline {{ if $isYear -}}search-text{{- end -}}">{{ $entry.Year }}</div>
|
||||||
|
{{- else -}}
|
||||||
|
<div class="inline">o.J.</div>
|
||||||
|
{{- end -}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{- $srels := index $model.result.EntriesSeries $entry.Id -}}
|
||||||
|
{{- if $srels -}}
|
||||||
|
<div class="flex flex-row flex-wrap py-1 gap-y-1">
|
||||||
|
{{- range $_, $srel := $srels -}}
|
||||||
|
{{- $series := index $model.result.Series $srel.Series -}}
|
||||||
|
{{- if $series -}}
|
||||||
|
<div class="inline-flex flex-row text-base font-sans px-2 bg-zinc-100 rounded mr-2">
|
||||||
|
<span class="border-r pr-2 border-gray-300">Reihentitel</span
|
||||||
|
><a
|
||||||
|
href="/reihe/{{ $series.MusenalmID }}"
|
||||||
|
class="no-underline pl-2 block {{ if
|
||||||
|
$isSeries
|
||||||
|
-}}
|
||||||
|
search-text
|
||||||
|
{{- end -}}">
|
||||||
|
<b>{{- $series.Title -}}</b>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- $arels := index $model.result.EntriesAgents $entry.Id -}}
|
||||||
|
{{- if $arels -}}
|
||||||
|
<div class="flex flex-row flex-wrap py-1 gap-y-1">
|
||||||
|
{{- range $_, $arel := $arels -}}
|
||||||
|
{{- $agent := index $model.result.Agents $arel.Agent -}}
|
||||||
|
{{- if $agent -}}
|
||||||
|
<div class="inline-block text-base font-sans bg-slate-100 rounded mr-2">
|
||||||
|
<span class="border-r px-2 border-gray-300"> {{- $arel.Type -}} </span
|
||||||
|
><a
|
||||||
|
href="/person/{{ $agent.Id }}"
|
||||||
|
class="no-underline px-1.5 {{ if
|
||||||
|
$isPersons
|
||||||
|
-}}
|
||||||
|
search-text
|
||||||
|
{{- end -}}">
|
||||||
|
<b>{{- $agent.Name -}}</b>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $entry.Annotation -}}
|
||||||
|
<div class="text-base hyphens-auto">
|
||||||
|
<b>Anm.: </b
|
||||||
|
><span class="{{- if $isAnnotations -}}search-text{{- end -}}"
|
||||||
|
>{{- Safe
|
||||||
|
(ReplaceSlashParenSlash $entry.Annotation)
|
||||||
|
-}}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
{{- end -}}
|
||||||
|
<div class="pb-4"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<label for="q" class="hidden">Suchbegriffe</label>
|
<label for="q" class="hidden">Suchbegriffe</label>
|
||||||
<input
|
<input
|
||||||
{{ if $q }}value="{{ $q }}"{{- end -}}
|
{{ if $q }}value="{{ $q }}"{{- end }}
|
||||||
type="search"
|
type="search"
|
||||||
name="q"
|
name="q"
|
||||||
minlength="3"
|
minlength="3"
|
||||||
|
|||||||
Reference in New Issue
Block a user