AgentSkillsCN

create-blog-article

为 Calorize 博客撰写一篇全新的博客文章。适用于用户提出“创建”、“添加”或“撰写”新博客文章、新博文或新博客条目时使用。支持 Blade 模板、路由、博客首页、站点地图、本地化,以及封面图片的自动生成与优化。

SKILL.md
--- frontmatter
name: create-blog-article
description: Creates a new blog article for the Calorize blog. Use when the user asks to create, add, or write a new blog post, article, or blog entry. Handles Blade template, route, blog index, sitemap, localization, and cover image.

Create Blog Article

Overview

The Calorize blog uses static Blade templates with Laravel localization (__()). Each article requires changes to 6 files. Follow every step — missing one breaks the article.

Pre-flight

  1. Determine the next blog number: check routes/web.php for the highest blog-N route. The new article is blog-{N+1}.
  2. Read the latest article (resources/views/blog/blog-{N}.blade.php) to match current markup and style conventions exactly.
  3. Read resources/views/blog/index.blade.php to see the blog listing arrays ($sciencePosts, $practicalPosts).
  4. Determine the article category: "Science" articles go in $sciencePosts; practical/product articles go in $practicalPosts.
  5. Determine the article date: use today's date unless the user specifies one.

Step-by-step Checklist

1. Create the Blade template

File: resources/views/blog/blog-{N+1}.blade.php

Copy the structure from the latest existing article. Key rules:

  • Wrap in <x-app-layout :full-width="true">.
  • All user-facing text in {{ __('English text') }} or {!! __('Text with <strong>HTML</strong>') !!}.
  • English is the source language inside __(). The Ukrainian original goes into uk.json.
  • @section('title') — article title.
  • @section('meta')description, keywords, author.
  • The $primaryUrl / $primaryLabel pattern for CTA buttons.
  • Tag badge color: Science = bg-sky-500, Market Analysis = bg-rose-500, Product Update = bg-emerald-500.
  • Image path: /images/blog/blog-{N+1}.jpg (or .svg/.webp to match the provided asset).
  • Date in <time datetime="YYYY-MM-DD"> using Carbon::parse()->translatedFormat('d M Y').
  • End with a CTA card that has a contextual headline and both "primary action" and "Read other articles" buttons.
  • Links to external sources: target="_blank", styled text-sky-600 hover:underline text-sm break-words.
  • Never use markdown in the template. Plain Blade + Tailwind only.

2. Register the route

File: routes/web.php

Add after the last blog-{N} route, before the /blog index route:

php
Route::get('/blog/{slug-transliterated-from-ukrainian-title}', function () {
    return view('blog.blog-{N+1}');
})->name('blog-{N+1}');

The slug is a transliterated version of the Ukrainian title (lowercase, hyphens, no special chars). Use a consistent transliteration style matching existing slugs.

3. Update the blog index

File: resources/views/blog/index.blade.php

Add the new article entry at the top of the appropriate array ($sciencePosts or $practicalPosts):

php
[
    'href' => route('blog-{N+1}'),
    'title' => __('English Article Title'),
    'excerpt' => __('Short 1-2 sentence excerpt.'),
    'image' => '/images/blog/blog-{N+1}.jpg',
    'tag' => __('Science'),        // or 'Market Analysis', 'Product Update', etc.
    'time' => __('7 min read'),    // estimate based on content length
    'date' => 'YYYY-MM-DD',
],

4. Update the sitemap

File: app/Console/Commands/GenerateSitemap.php

Add to the $blogPosts array:

php
'blog-{N+1}' => 'YYYY-MM-DD',

5. Add Ukrainian translations

File: resources/lang/uk.json

Add every string used in __() in the new article. This includes:

  • Title, meta description, meta keywords
  • Every paragraph, heading, list item, button label, CTA text
  • Reuse existing keys when possible (e.g., "Back to Blog", "Read other articles", "Science" are already translated)

Format: "English source text": "Українська переклад" — append at the end of the JSON object before the closing }.

Critical: The user provides Ukrainian text as the original. The English in __() is the translation. The uk.json maps English back to Ukrainian.

6. Add the cover image

If the user provides an image:

  1. Check the format with file and sips -g all (on macOS).
  2. Copy/convert to public/images/blog/blog-{N+1}.jpg (or appropriate extension).
  3. If the image is PNG and large, convert to JPEG: sips -s format jpeg input.png --out output.jpg.
  4. Target: JPEG, reasonable web size (< 200KB ideally), aspect ratio ~16:9 to match the aspect-[16/9] container.

If no image is provided, note that an image placeholder is needed.

Translation Guidelines

  • The user typically provides content in Ukrainian. The article template uses English as the __() key.
  • Write natural, fluent English for the template — not mechanical translation.
  • Write natural, fluent Ukrainian for uk.json — preserve the original tone, emoji, and style.
  • Keep emoji in both languages where used.
  • External URLs stay the same in both languages.

Verification

After creating all files:

  1. Confirm all 6 files were modified/created.
  2. Check that the route name in web.php matches what's used in index.blade.php and GenerateSitemap.php.
  3. Verify no duplicate keys were added to uk.json.
  4. Confirm the image file exists at the referenced path.