Capstone: blog

Contents
The spec
Posts CRUD
Comments
Smoke tests

The spec

The capstone ties the course together: a tiny blog with posts, comments, and a guarded admin area. Build it in order: routes first, then pages, then forms, then login. Four routes cover the whole project.

GET /posts - list, GET /posts/id - read one

GET /admin/posts - manage, POST /admin/posts - create

Posts CRUD

Posts are standard CRUD: list them, show one, create and edit behind login. One controller with one route per action keeps the shape clear, and the controller extends the base controller for templates and redirects.

use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class PostController { #[Route("/posts", methods: ["GET"])] public function list(PostRepository $posts): Response { return $this->render("post/list.html.twig", [ "posts" => $posts->findAll(), ]); } }

Comments

Comments belong to posts through a many-to-one relation from comment to post. Render the comment form under the post and save through the same entity manager, so one flush stores the comment with its link to the post.

use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Comment { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 500)] private string $body = ""; public function getId(): ?int { return $this->id; } }

Smoke tests

Finish with tests that load every public page and submit one form. They run in seconds and catch broken routes before visitors do, which is exactly the safety net a first project needs.

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class BlogSmokeTest extends WebTestCase { public function testListLoads(): void { $client = static::createClient(); $client->request("GET", "/posts"); $this->assertResponseIsSuccessful(); } }

Next: Capstone: JSON API

Article author: Arthur Isaev

Related articles
Development with PHP
What is Symfony and where it runs
Install Symfony
Your first page
Routes
Controllers
Twig basics
Twig advanced
Doctrine setup
Entities
Migrations
Repositories
Relations
Forms
Validation
Services and DI
JSON controllers
Serializer
Security intro
Users
Login form
Voters
Console commands
Events
Messenger
Mailer
Cache
Sessions
CSRF
Translations
Dotenv and env
Profiler
Testing
Fixtures
Pagination
File uploads
API Platform in one lesson
DQL
Transactions
Migrations advanced
Security advanced
HTTP client
Scheduler
Webhooks
Asset Mapper
Deployment
Performance
Capstone: blog
Capstone: JSON API
Modern Symfony tour
Hero roadmap: the whole course on one page

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: