feat: custom content type icons, built-in types, user lookup
This commit is contained in:
1 parent
e6e088c963
commit
73a75d5cb9
31 files changed
+1611
-36
No files matched your search
@@ -0,0 +1,141 @@
|
||||
package builtintype
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/contenttype"
|
||||
"RenewCMS/internal/domain/user"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("built-in type not found")
|
||||
|
||||
const (
|
||||
KeyArticle = "article"
|
||||
KeyAuthor = "author"
|
||||
KeySite = "site"
|
||||
KeyMedia = "media"
|
||||
KeyUser = "user"
|
||||
)
|
||||
|
||||
type Type struct {
|
||||
Key string `json:"key"`
|
||||
Name string `json:"name"`
|
||||
Fields []contenttype.Field `json:"fields"`
|
||||
}
|
||||
|
||||
func Catalogue() []Type {
|
||||
return []Type{
|
||||
{Key: KeyArticle, Name: "Articles", Fields: articleFields()},
|
||||
{Key: KeyAuthor, Name: "Authors", Fields: authorFields()},
|
||||
{Key: KeySite, Name: "Sites", Fields: siteFields()},
|
||||
{Key: KeyMedia, Name: "Media", Fields: mediaFields()},
|
||||
{Key: KeyUser, Name: "Users", Fields: userFields()},
|
||||
}
|
||||
}
|
||||
|
||||
func Find(key string) (Type, error) {
|
||||
for _, candidate := range Catalogue() {
|
||||
if candidate.Key == key {
|
||||
return candidate, nil
|
||||
}
|
||||
}
|
||||
return Type{}, ErrNotFound
|
||||
}
|
||||
|
||||
func field(key string, label string, fieldType contenttype.FieldType) contenttype.Field {
|
||||
return contenttype.Field{Key: key, Label: label, Type: fieldType, Options: []string{}}
|
||||
}
|
||||
|
||||
func (b builder) required() builder {
|
||||
b.Required = true
|
||||
return b
|
||||
}
|
||||
|
||||
func (b builder) min(bound int) builder {
|
||||
b.Min = bound
|
||||
return b
|
||||
}
|
||||
|
||||
func (b builder) max(bound int) builder {
|
||||
b.Max = bound
|
||||
return b
|
||||
}
|
||||
|
||||
func (b builder) options(options ...string) builder {
|
||||
b.Options = options
|
||||
return b
|
||||
}
|
||||
|
||||
type builder contenttype.Field
|
||||
|
||||
func text(key string, label string) builder {
|
||||
return builder(field(key, label, contenttype.TypeText))
|
||||
}
|
||||
|
||||
func of(key string, label string, fieldType contenttype.FieldType) builder {
|
||||
return builder(field(key, label, fieldType))
|
||||
}
|
||||
|
||||
func build(builders ...builder) []contenttype.Field {
|
||||
fields := make([]contenttype.Field, 0, len(builders))
|
||||
for _, b := range builders {
|
||||
fields = append(fields, contenttype.Field(b))
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func articleFields() []contenttype.Field {
|
||||
return build(
|
||||
text("title", "Title").required().min(article.MinTitleRunes).max(article.MaxTitleRunes),
|
||||
of("body", "Body", contenttype.TypeRichText),
|
||||
text("slug", "Slug"),
|
||||
text("excerpt", "Excerpt").max(300),
|
||||
text("seo_title", "SEO title").max(120),
|
||||
text("seo_description", "SEO description").max(320),
|
||||
of("is_online", "Online", contenttype.TypeBoolean),
|
||||
text("canonical_url", "Canonical URL").max(article.MaxCanonicalURLRunes),
|
||||
of("noindex", "No index", contenttype.TypeBoolean),
|
||||
)
|
||||
}
|
||||
|
||||
func authorFields() []contenttype.Field {
|
||||
return build(
|
||||
text("name", "Name").required(),
|
||||
text("slug", "Slug"),
|
||||
text("bio", "Bio"),
|
||||
text("website", "Website"),
|
||||
)
|
||||
}
|
||||
|
||||
func siteFields() []contenttype.Field {
|
||||
return build(
|
||||
text("name", "Name").required(),
|
||||
text("key", "Key").required(),
|
||||
text("base_url", "Base URL").required(),
|
||||
of("default_robots", "Default robots", contenttype.TypeSelect).options("index", "noindex"),
|
||||
text("locale", "Locale"),
|
||||
of("is_default", "Default site", contenttype.TypeBoolean),
|
||||
text("site_name", "Site name").max(100),
|
||||
text("title_template", "Title template").max(200),
|
||||
text("default_description", "Default description").max(320),
|
||||
)
|
||||
}
|
||||
|
||||
func mediaFields() []contenttype.Field {
|
||||
return build(
|
||||
text("filename", "Filename"),
|
||||
of("size", "Size", contenttype.TypeNumber),
|
||||
of("width", "Width", contenttype.TypeNumber),
|
||||
of("height", "Height", contenttype.TypeNumber),
|
||||
text("content_type", "Content type"),
|
||||
)
|
||||
}
|
||||
|
||||
func userFields() []contenttype.Field {
|
||||
return build(
|
||||
text("username", "Username").required(),
|
||||
text("display_name", "Display name"),
|
||||
text("email", "Email").required(),
|
||||
of("role", "Role", contenttype.TypeSelect).required().options(string(user.RoleOwner), string(user.RoleAdmin)),
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user