feat(api): list an author's published posts at /authors/{author}/posts
- AuthorPosts reuses the /posts published predicate, per_page clamp, sort allow-list and row serializer - Bearer tokens are ignored; drafts and scheduled posts never appear - Both author routes share one resolve-or-respond helper for identical 404/500 paths - Document query keys, envelope and 404 in README
This commit is contained in:
19
README.md
19
README.md
@@ -21,7 +21,7 @@ WinterCMS theme components such as `journalPost` and `journalPosts` are a later
|
||||
- **Posts.** `models.Post` maps `golem15_journal_posts`. Translatable fields are title, content, content_html, excerpt, metadata, and slug (indexed). Fillable does not include `redactor_id`, `content_html`, or `user_id`. Attachments `featured_images` and `content_images` use `system_files` under the same MorphName. YAML admin uses `mltext`/`mlmarkdown`. `classes.FormatHTML` regenerates `content_html` on admin save.
|
||||
- **Categories and tags.** `models.Category` is translatable (name, description, slug). Fillable is name, slug, code, description, parent_id; nest_* columns exist in DDL and are not fillable. `models.Tag` is not translatable. Fillable is name, slug, description. Pivots are `golem15_journal_posts_categories` and `golem15_journal_posts_tags`.
|
||||
- **Settings.** Singleton row ID=1 on `golem15_journal_settings`, not PHP `system_settings`. `search_use_typesense` defaults to false. A fresh save never contacts Typesense.
|
||||
- **Public HTTP.** Anonymous GET `/_journal/api/v1/posts`, `/posts/{slug}`, `/categories`, `/tags`, `/rss`, and `/authors/{author}`. Writes under the same prefix require a cabana backend JWT (`aud=backend`).
|
||||
- **Public HTTP.** Anonymous GET `/_journal/api/v1/posts`, `/posts/{slug}`, `/categories`, `/tags`, `/rss`, `/authors/{author}`, and `/authors/{author}/posts`. Writes under the same prefix require a cabana backend JWT (`aud=backend`).
|
||||
- **Author slug.** Plugin migration adds `backend_users.golem15_bloghub_author_slug`. The column stores the public author slug that the author routes resolve.
|
||||
- **Import and export.** `journal:export-posts` and `journal:import-posts` write and read one JSON file per post. The Posts list toolbar exposes the same actions to administrators with `golem15.journal.access_import_export`.
|
||||
- **Phrasebooks.** Embedded `lang/en/lang.yaml` and `lang/pl/lang.yaml` hold plugin, journal, post, category, and tag UI strings. They are independent of model translation JSON.
|
||||
@@ -77,6 +77,7 @@ GET /_journal/api/v1/categories
|
||||
GET /_journal/api/v1/tags
|
||||
GET /_journal/api/v1/rss
|
||||
GET /_journal/api/v1/authors/jane-doe
|
||||
GET /_journal/api/v1/authors/jane-doe/posts?page=2
|
||||
```
|
||||
|
||||
### Public author API
|
||||
@@ -100,6 +101,22 @@ An unknown author, a login without published posts, a soft-deleted user and a ma
|
||||
{"error":"Author not found"}
|
||||
```
|
||||
|
||||
`GET /_journal/api/v1/authors/{author}/posts` lists that author's published posts (`published` true and `published_at` in the past), resolving `{author}` the same way. Rows have the same shape as `GET /_journal/api/v1/posts` rows. Bearer tokens are ignored, so an editor also sees published posts only. Query keys:
|
||||
|
||||
| Key | Default | Notes |
|
||||
|-----|---------|-------|
|
||||
| `page` | `1` | Values below 1 or non-numeric fall back to page 1. |
|
||||
| `per_page` | `9` | Clamped to 1..30. |
|
||||
| `sort` | `published_at desc` | Same columns as `/posts`: `published_at`, `created_at`, `updated_at`, `title`, `id`, each `asc` or `desc`. |
|
||||
|
||||
The response uses the `/posts` pagination envelope (rows trimmed here):
|
||||
|
||||
```json
|
||||
{"data":[{"id":12,"slug":"hello-world","title":"Hello world","author":{"id":7,"first_name":"Jane","last_name":"Doe","login":"jdoe"}}],"meta":{"current_page":2,"last_page":2,"per_page":9,"total":10}}
|
||||
```
|
||||
|
||||
An author that does not resolve answers the same `404 {"error":"Author not found"}` as the profile route.
|
||||
|
||||
Editors create a post with a cabana backend JWT (audience `backend`):
|
||||
|
||||
```http
|
||||
|
||||
Reference in New Issue
Block a user