mirror of
https://github.com/andwati/andwati.com.git
synced 2026-10-18 01:12:53 +00:00
Define Strapi content types matching the content/ schema
Adds writing, portfolio-entry, bookshelf-entry, and curated-blog collection types with attributes mirroring the TOML frontmatter fields in content/README.md exactly, so the future sync provider has a direct field mapping. draftAndPublish is disabled on all four since our own `draft` boolean (synced to the file) is the source of publish state, not Strapi's built-in workflow. Verified Strapi boots and registers all four REST routes (api/writings, api/portfolio-entries, api/bookshelf-entries, api/curated-blogs).
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "bookshelf_entries",
|
||||
"info": {
|
||||
"singularName": "bookshelf-entry",
|
||||
"pluralName": "bookshelf-entries",
|
||||
"displayName": "Bookshelf Entry",
|
||||
"description": "Books and papers, synced to content/bookshelf/. `kind` selects which identifier fields apply."
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
},
|
||||
"attributes": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"kind": {
|
||||
"type": "enumeration",
|
||||
"enum": ["book", "paper"],
|
||||
"required": true
|
||||
},
|
||||
"authors": {
|
||||
"type": "json",
|
||||
"description": "Array of author name strings"
|
||||
},
|
||||
"isbn": {
|
||||
"type": "string",
|
||||
"description": "Books only"
|
||||
},
|
||||
"doi": {
|
||||
"type": "string",
|
||||
"description": "Papers only"
|
||||
},
|
||||
"arxiv_id": {
|
||||
"type": "string",
|
||||
"description": "Papers only, optional"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "Papers only: landing page / source link"
|
||||
},
|
||||
"cover_image": {
|
||||
"type": "string",
|
||||
"description": "Path to the locally cached cover, e.g. /covers/slug.jpg"
|
||||
},
|
||||
"rating": {
|
||||
"type": "integer",
|
||||
"min": 1,
|
||||
"max": 5
|
||||
},
|
||||
"status": {
|
||||
"type": "enumeration",
|
||||
"enum": ["reading", "read", "abandoned"]
|
||||
},
|
||||
"date_started": {
|
||||
"type": "date"
|
||||
},
|
||||
"date_finished": {
|
||||
"type": "date"
|
||||
},
|
||||
"tags": {
|
||||
"type": "json",
|
||||
"description": "Array of tag strings, maps to [taxonomies].tags"
|
||||
},
|
||||
"body": {
|
||||
"type": "richtext",
|
||||
"description": "Personal review/notes below the frontmatter"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController(
|
||||
"api::bookshelf-entry.bookshelf-entry",
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreRouter(
|
||||
"api::bookshelf-entry.bookshelf-entry",
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreService(
|
||||
"api::bookshelf-entry.bookshelf-entry",
|
||||
);
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "curated_blogs",
|
||||
"info": {
|
||||
"singularName": "curated-blog",
|
||||
"pluralName": "curated-blogs",
|
||||
"displayName": "Curated Blog",
|
||||
"description": "Hand-picked external blogs, synced to content/blogs/. No live feed fetching."
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
},
|
||||
"attributes": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"feed_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"body": {
|
||||
"type": "richtext",
|
||||
"description": "One-to-two sentence blurb below the frontmatter"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController("api::curated-blog.curated-blog");
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreRouter("api::curated-blog.curated-blog");
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreService("api::curated-blog.curated-blog");
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "portfolio_entries",
|
||||
"info": {
|
||||
"singularName": "portfolio-entry",
|
||||
"pluralName": "portfolio-entries",
|
||||
"displayName": "Portfolio Entry",
|
||||
"description": "Projects and professional work, synced to content/portfolio/."
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
},
|
||||
"attributes": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
},
|
||||
"date_start": {
|
||||
"type": "date"
|
||||
},
|
||||
"date_end": {
|
||||
"type": "date"
|
||||
},
|
||||
"outcome": {
|
||||
"type": "string"
|
||||
},
|
||||
"draft": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"links": {
|
||||
"type": "json",
|
||||
"description": "Array of { label, url }, maps to [[links]]"
|
||||
},
|
||||
"tags": {
|
||||
"type": "json",
|
||||
"description": "Array of tag strings, maps to [taxonomies].tags"
|
||||
},
|
||||
"body": {
|
||||
"type": "richtext",
|
||||
"description": "Markdown case-study body below the frontmatter"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController(
|
||||
"api::portfolio-entry.portfolio-entry",
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreRouter(
|
||||
"api::portfolio-entry.portfolio-entry",
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreService(
|
||||
"api::portfolio-entry.portfolio-entry",
|
||||
);
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "writings",
|
||||
"info": {
|
||||
"singularName": "writing",
|
||||
"pluralName": "writings",
|
||||
"displayName": "Writing",
|
||||
"description": "Long-form essays and technical posts, synced to content/writings/."
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
},
|
||||
"attributes": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "date",
|
||||
"required": true
|
||||
},
|
||||
"updated": {
|
||||
"type": "date"
|
||||
},
|
||||
"draft": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"canonical_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "json",
|
||||
"description": "Array of tag strings, maps to [taxonomies].tags"
|
||||
},
|
||||
"series": {
|
||||
"type": "string",
|
||||
"description": "Maps to [extra].series"
|
||||
},
|
||||
"series_index": {
|
||||
"type": "integer",
|
||||
"description": "Maps to [extra].series_index"
|
||||
},
|
||||
"llms_description": {
|
||||
"type": "text",
|
||||
"description": "Maps to [extra].llms_description"
|
||||
},
|
||||
"body": {
|
||||
"type": "richtext",
|
||||
"description": "Markdown body below the frontmatter"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreController("api::writing.writing");
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreRouter("api::writing.writing");
|
||||
@@ -0,0 +1,3 @@
|
||||
import { factories } from "@strapi/strapi";
|
||||
|
||||
export default factories.createCoreService("api::writing.writing");
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
* The app doesn't have any components yet.
|
||||
*/
|
||||
+1135
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -12,7 +12,8 @@
|
||||
"scripts/**",
|
||||
"!apps/**/dist",
|
||||
"!apps/**/.strapi",
|
||||
"!apps/**/public"
|
||||
"!apps/**/public",
|
||||
"!apps/**/types/generated"
|
||||
]
|
||||
},
|
||||
"formatter": {
|
||||
|
||||
Reference in New Issue
Block a user