Skip to content

Commit 581de22

Browse files
committed
readme.md complete with instructions
1 parent 389a232 commit 581de22

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Adding an article
2+
3+
Steps to publish a new article and regenerate the public artifacts that depend on it.
4+
5+
## 1. Add the article data
6+
7+
Add a new entry to the category's `articles` array in `src/App/src/Fixture/articles_cleaned.json`:
8+
9+
```json
10+
{
11+
"post_title": "Your article title",
12+
"post_date": "YYYY-MM-DD HH:MM:SS",
13+
"post_status": "publish",
14+
"author": {
15+
"display_name": "admin",
16+
"github": "arhimede"
17+
},
18+
"isObsolete": false,
19+
"opengraph_img": null,
20+
"excerpt": "Short excerpt shown in listings.",
21+
"tl_dr": "One or two sentence summary."
22+
}
23+
```
24+
25+
`author.display_name` can either match an existing author or be a new name — `bin/doctrine-fixtures` creates a new `Author` automatically for any name not already in the database. The category (top-level `slug`) must already exist, though. The article's slug is derived automatically from the title (lowercased, non-alphanumeric characters collapsed to `-`) by `PostLoader::slugify()`.
26+
27+
`opengraph_img` is the image shown as the social-media (Twitter/OG) preview card. Leave it `null` to fall back to the site-wide default image (`config/autoload/local.php``application.meta.image`). To set one, put the image file at `public/opengraph/article/your-image.png` and reference it here as a root-relative path: `"opengraph_img": "/opengraph/article/your-image.png"`. This is unrelated to the in-article images described in step 3 — it is placed by hand, not by `bin/create-uploads-dir`.
28+
29+
**Important:** you can set `"post_status": "draft"` instead of `"publish"` to keep an article out of sight — anything other than `publish`/`private` is treated as a draft by `PostLoader`, and `getPublishedPosts()` (used by both `bin/generate-feed` and `bin/sitemap`) only returns posts with `publish` status. After changing it, follow the same steps: re-run `bin/doctrine-fixtures`, then `bin/generate-feed` and `bin/sitemap`. This applies generally, not just to status changes — **any** edit to `articles_cleaned.json` (title, excerpt, status, date, etc.) needs `bin/doctrine-fixtures` re-run to update the database, followed by re-running the 3 generators in step 4 so `feed.xml`/`sitemap.xml`/`llms-full.txt` reflect it. One exception: `bin/generate-llms-full` reads straight from the `.md` files on disk and does **not** check `post_status` at all — a `draft` article's `.md` file will still be included in `llms-full.txt` unless you also remove or rename that file.
30+
31+
## 2. Create the templates
32+
33+
- `src/Blog/templates/page/blog-resource/{category-slug}/{article-slug}.html.twig` — the page body, extending `@layout/blog-post.html.twig`.
34+
- `src/Blog/templates/page/JSON-LD/{category-slug}/{article-slug}.jsonld.twig` — the `@graph` of `TechArticle` + `BreadcrumbList` + `FAQPage` structured data.
35+
- `public/md-articles/{category-slug}/{article-slug}.md` — the markdown version, with YAML front matter (`title`, `description`, `author`, `date_published`, `canonical_url`, `category`, `language`) followed by the article body (`TL;DR`, sections, `FAQ`). This feeds `llms-full.txt`.
36+
37+
Copy an existing set of these three files in the same category as a starting point, to match the established structure (FAQ block matching the `FAQPage` entries, etc.).
38+
39+
If the article body uses images (via `asset('uploads/article/' ~ article.id ~ '/filename.png')` in the `.html.twig`), just drop the image file anywhere under `public/uploads``bin/create-uploads-dir` (step 4) finds it by filename and copies it to the right place. No manual path/folder creation needed.
40+
41+
## 3. At deploy — run in this order
42+
43+
```
44+
php bin/doctrine-fixtures
45+
php bin/create-uploads-dir
46+
```
47+
48+
- `bin/doctrine-fixtures` loads `articles_cleaned.json` into the database, creating the `Post` entity (with its database-generated UUID) for the new article.
49+
- `bin/create-uploads-dir` must run *after* it — it resolves the post by slug to get that UUID, creates `public/uploads/article/{post-id}/`, and copies each image referenced in the `.html.twig` there from wherever it already lives under `public/uploads`.
50+
51+
## 4. Regenerate the public artifacts — any order
52+
53+
```
54+
php bin/generate-feed
55+
php bin/sitemap
56+
php bin/generate-llms-full
57+
```
58+
59+
- `bin/generate-feed` rewrites `public/feed.xml` from the published posts in the database.
60+
- `bin/sitemap` rewrites `public/sitemap.xml` from the published posts in the database.
61+
- `bin/generate-llms-full` rewrites `public/llms-full.txt` by concatenating `public/md-articles/index.md` and every other `public/md-articles/*/*.md` file, sorted by path. Requires the `llms.sourceDir` / `llms.outputFile` keys in `config/autoload/local.php` (see `local.php.dist`).
62+
63+
These three have no ordering dependency on each other, only on step 3 being done first.
64+
65+
Note: none of this is wired into an automated deploy pipeline in this repository — there is no `deploy` script or CI job that runs these `bin/` scripts. They're run manually (or via cron, as already set up for `bin/generate-packages`). `public/feed.xml`, `public/sitemap.xml`, and `public/llms-full.txt` are committed generated artifacts, so re-running these scripts leaves them modified in git until committed.

0 commit comments

Comments
 (0)