Installation
composer require cedricziel/blog-bundle
Add to config/bundles.php:
Cedricziel\BlogBundle\CedriczielBlogBundle::class => ['all' => true],
Database Migration
Run migrations (if included) or manually create tables based on the bundle’s Schema (check Resources/config/doctrine/ for YAML/XML definitions).
First Use Case
Post entity via the bundle’s CRUD interface (if provided) or manually:
use Cedricziel\BlogBundle\Entity\Post;
$post = new Post();
$post->setTitle('Hello World');
$post->setContent('First blog post!');
$em->persist($post);
$em->flush();
use Cedricziel\BlogBundle\Entity\Post;
use Doctrine\ORM\EntityManagerInterface;
public function index(EntityManagerInterface $em)
{
$posts = $em->getRepository(Post::class)->findAll();
return $this->render('blog/index.html.twig', ['posts' => $posts]);
}
Routing
Check Resources/config/routing.yml for default routes (e.g., /blog/{slug}). Override or extend as needed.
Entity Management
Post entity (e.g., add custom fields) by overriding the bundle’s Post class.
namespace App\Entity;
use Cedricziel\BlogBundle\Entity\Post as BasePost;
class Post extends BasePost
{
// Custom fields/methods
}
Category/Tag entities similarly.Repository Patterns
public function getFeaturedPosts(EntityManagerInterface $em, int $limit = 3)
{
return $em->getRepository(Post::class)
->createQueryBuilder('p')
->where('p.published = :published')
->setParameter('published', true)
->orderBy('p.createdAt', 'DESC')
->setMaxResults($limit)
->getQuery()
->getResult();
}
Form Handling
PostType (if provided) or create a custom form:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('content', TextareaType::class)
->add('published', CheckboxType::class);
}
}
Twig Integration
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.content|truncate(200) }}</p>
<a href="{{ path('blog_show', {'slug': post.slug}) }}">Read more</a>
{% endfor %}
Event Listeners
prePersist for slug generation):
// src/EventListener/PostListener.php
public function prePersist(Post $post)
{
if (empty($post->getSlug())) {
$post->setSlug(StringUtil::slugify($post->getTitle()));
}
}
Register in services.yaml:
services:
App\EventListener\PostListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
composer.json:
"autoload": {
"psr-4": {
"Cedricziel\\BlogBundle\\": "vendor/cedricziel/blog-bundle/src/"
}
}
vendor/cedricziel/blog-bundle/Resources/public/ to public/bundles/blog/.Post repository in PHPUnit:
$this->entityManager->getRepository(Post::class)
->method('findAll')
->willReturn([$mockPost]);
Lack of Documentation
No Default Fixtures
Routing Conflicts
config/routes.yaml:
blog:
resource: "@CedriczielBlogBundle/Resources/config/routing.yml"
prefix: "/my-custom-prefix"
Entity Inheritance
Post may break bundle updates. Prefer composition (e.g., add a PostExtension trait) or use Doctrine Extensions.Translation Support
translatable behavior:
# config/packages/gedmo_translatable.yaml
gedmo_translatable:
default_locale: en
ignore_fields: [slug, createdAt]
Post entity is mapped correctly. Check:
vendor/cedricziel/blog-bundle/src/Entity/Post.php for annotations.config/packages/doctrine.yaml for orm mappings.php bin/console cache:clear) and verify routing.yml paths.Post entity:
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\NotBlank
* @Assert\Length(min=10)
*/
private $content;
Custom Fields
Add fields to Post and update forms/repositories:
// Add to Post entity
private $views = 0;
// Add to PostType
->add('views', HiddenType::class)
Increment views via a listener:
public function postView(Post $post)
{
$post->setViews($post->getViews() + 1);
$em->flush();
}
API Endpoints Use ApiPlatform or manually create controllers:
#[Route('/api/posts', name: 'api_posts', methods: ['GET'])]
public function getPosts(EntityManagerInterface $em): JsonResponse
{
$posts = $em->getRepository(Post::class)->findAll();
return new JsonResponse($posts);
}
Search Functionality Integrate with Elasticsearch or Algolia:
// Example: Sync posts to Algolia
$client->saveObjects([
[
'objectID' => $post->getId(),
'title' => $post->getTitle(),
// ...
]
]);
Media Handling Use VichUploaderBundle for file uploads:
// Add to Post entity
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[Vich\Uploadable]
private ?File $imageFile;
php bin/console doctrine:migrations:execute --up
Otherwise, manually create tables based on the bundle’s Schema files.%env% or env() in services:
# config/services.yaml
parameters:
blog.posts_per_page: '%env(int:POSTS_PER_PAGE, 10)%'
How can I help you explore Laravel packages today?