Install via Composer
composer require desarrolla2/blog-bundle
Ensure your AppKernel.php includes the bundle in the registerBundles() method:
$bundles[] = new Desarrolla2\BlogBundle\Desarrolla2BlogBundle();
Run Migrations The bundle includes Doctrine migrations for its entities. Run:
php app/console doctrine:migrations:diff
php app/console doctrine:migrations:migrate
Configure Routes
Import the bundle’s routing in app/config/routing.yml:
desarrolla2_blog:
resource: "@Desarrolla2BlogBundle/Resources/config/routing.yml"
prefix: /blog
First Use Case: Create a Post Use the provided controller to create a post via the admin interface (if enabled) or manually via the API:
use Desarrolla2\BlogBundle\Entity\Post;
$post = new Post();
$post->setTitle('My First Post');
$post->setSlug('my-first-post');
$post->setContent('Hello, world!');
$em->persist($post);
$em->flush();
SEO-Friendly URLs
Slugs are auto-generated from titles (e.g., My First Post → my-first-post). Override in Post entity:
public function setTitle($title) {
$this->title = $title;
$this->slug = Str::slug($title); // Use Laravel's Str helper or Symfony's StringUtil
}
Taxonomy Management
Attach categories/tags to posts via the ManyToMany relation:
$post->addCategory($categoryEntity);
$post->addTag($tagEntity);
Fetch posts by taxonomy in controllers:
$posts = $em->getRepository('Desarrolla2BlogBundle:Post')
->findByTaxonomy('category', 'technology');
CKEditor Integration
Configure CKEditor in config.yml:
desarrolla2_blog:
ckeditor:
toolbar: 'Basic'
height: '300px'
Use the ckeditor Twig extension in forms:
{{ form_widget(form.content, {'attr': {'class': 'ckeditor'}}) }}
Image Uploads
Upload images via the PostImage entity. Use the provided upload handler in controllers:
$post->uploadImage($request->files->get('image'));
Store uploads in web/uploads/blog/ (configurable in config.yml).
Comments System
Enable comments in config.yml:
desarrolla2_blog:
comments: true
Fetch comments for a post:
$comments = $post->getComments();
Moderate comments via the admin interface or manually:
$comment->setApproved(true);
$em->flush();
HTTP Caching Leverage Symfony’s HTTP cache for static blog pages:
# app/config/config.yml
framework:
esi: { enabled: true }
http_cache:
enabled: true
app/Resources/Desarrolla2BlogBundle/views/ to modify layouts (e.g., Post/show.html.twig).Post or Comment entities in your bundle to add custom fields:
namespace AppBundle\Entity;
use Desarrolla2\BlogBundle\Entity\Post as BasePost;
class Post extends BasePost {
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $customField;
}
use FOS\RestBundle\Controller\Annotations\Route;
use FOS\RestBundle\Controller\Annotations\Get;
class PostController extends Controller {
/**
* @Route("/api/posts", name="api_posts")
* @Get
*/
public function getPostsAction() {
$posts = $this->getDoctrine()->getRepository('Desarrolla2BlogBundle:Post')->findAll();
return $this->handleView($this->view($posts, 200));
}
}
Symfony 2.3 Legacy
SecurityBundle).symfony/symfony v2.3 or isolate the bundle in a subdirectory.Missing Laravel-Specific Features
Storage facade for file uploads:
use Illuminate\Support\Facades\Storage;
Storage::disk('public')->put('blog/' . $filename, $file->getContent());
CKEditor Configuration
config.yml:
desarrolla2_blog:
ckeditor:
config:
extraPlugins: 'image2,widget'
filebrowserImageBrowseUrl: '/ckfinder/browse.php?type=Images'
Taxonomy Performance
// Use DQL for complex queries
$query = $em->createQuery('
SELECT p FROM Desarrolla2BlogBundle:Post p
JOIN p.categories c WHERE c.name = :category
');
$query->setParameter('category', 'technology');
$posts = $query->getResult();
Image Upload Paths
web/uploads/blog/) may conflict with Laravel’s storage. Override in config.yml:
desarrolla2_blog:
upload_dir: '%kernel.root_dir%/../storage/app/public/blog'
public/storage:
php artisan storage:link
HTTP Cache Conflicts
# Disable Symfony HTTP cache if using Laravel's cache
framework:
http_cache: { enabled: false }
Doctrine Events
Listen for postPersist/postUpdate to debug entity changes:
$em->getEventManager()->addEventListener(
\Doctrine\ORM\Events::postPersist,
function ($event) {
$post = $event->getObject();
if ($post instanceof \Desarrolla2\BlogBundle\Entity\Post) {
\Log::debug('Post saved:', [$post->getTitle(), $post->getSlug()]);
}
}
);
Twig Debugging
Enable Twig debugging in config.yml:
twig:
debug: true
strict_variables: true
Check for template errors in var/log/dev.log.
Route Conflicts Ensure the bundle’s routes don’t clash with Laravel’s. Use route prefixes:
desarrolla2_blog:
resource: "@Desarrolla2BlogBundle/Resources/config/routing.yml"
prefix: /legacy_blog
Custom Post Types
Extend the Post entity to support custom content types (e.g., "Newsletter" vs. "Article"):
class Post extends BasePost {
/**
* @ORM\Column(type="string", length=50)
*/
private $type;
public function setType($type) {
$this->type = $type;
}
}
Filter posts by type in repositories:
$newsletters = $em->getRepository('AppBundle:Post')
->findBy(['type' => 'newsletter']);
Webhooks for Comments Trigger external actions (e.g., Slack notifications) when comments are posted:
$em->get
How can I help you explore Laravel packages today?