Install Dependencies
composer require ed/blog-bundle
composer require friendsofsymfony/user-bundle knplabs/knp-paginator-bundle stof/doctrine-extensions-bundle sonata-project/media-bundle
Enable Bundles
Add to config/bundles.php:
EtonDigital\EDBlogBundle\EDBlogBundle::class => ['all' => true],
Run Migrations
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Configure Routes
Import routing in config/routes.yaml:
ed_blog:
resource: "@EDBlogBundle/Resources/config/routing.yml"
prefix: /blog
First Admin Panel Access
Navigate to /blog/admin (ensure FOSUserBundle is configured with an admin user).
ed_blog.lock_enabled: true) to prevent concurrent edits.ed_blog.autosave_interval (default: 300s).config/packages/ed_blog.yaml:
ed_blog:
media:
providers: [sonata.media.provider.image, sonata.media.provider.file]
ROLE_CONTRIBUTOR, ROLE_AUTHOR, ROLE_EDITOR, ROLE_ADMIN).ed_blog.security.yml:
access_control:
- { path: ^/blog/admin, roles: ROLE_ADMIN }
- { path: ^/blog/article/new, roles: ROLE_AUTHOR }
ed_blog:
rss:
enabled: true
limit: 10
/blog/rss.use Knp\Component\Pager\PaginatorInterface;
$articles = $paginator->paginate(
$this->getDoctrine()->getRepository(Article::class)->findAll(),
$pageNumber, 10
);
templates/EDBlogBundle/ (e.g., article/show.html.twig).ed_blog.article.pre_publish):
// src/EventListener/ArticleListener.php
public function onPrePublish(ArticleEvent $event) {
$article = $event->getArticle();
$article->setSeoTitle($this->generateSeoTitle($article));
}
$article = $this->getDoctrine()->getRepository(Article::class)->find($id);
return $this->json($this->serializer->serialize($article, 'json'));
FOSUserBundle Dependency
fos_user is enabled in bundles.php.ROLE_ADMIN).php bin/console fos:user:create to create an admin user.Doctrine Extensions Conflict
StofDoctrineExtensionsBundle may cause issues if other bundles use the same extensions (e.g., Sluggable).config/packages/doctrine.yaml:
doctrine:
orm:
entity_managers:
default:
mappings:
StofDoctrineExtensionsBundle: ~
Media Upload Limits
config/packages/sonata_media.yaml:
sonata_media:
providers:
sonata.media.provider.image:
max_filesize: 10M
Autosave Overhead
ed_blog_article_revision table size.autosave_interval or disable for high-traffic sites.Routing Conflicts
/blog vs. /posts).config/routes/ed_blog.yaml:
ed_blog_article:
resource: "@EDBlogBundle/Resources/config/routing/article.yml"
prefix: /posts
APP_DEBUG=1 in .env to see detailed errors.var/log/dev.log for bundle-specific issues (e.g., media upload errors).# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Custom Fields
Add fields to Article via Doctrine extensions:
// src/Entity/Article.php
use Gedmo\Mapping\Annotation as Gedmo;
/**
* @Gedmo\Slug(fields={"title"})
*/
private $slug;
Plugin System Extend the bundle’s controller logic by overriding services:
# config/services.yaml
services:
ed_blog.article_controller:
class: App\Controller\CustomArticleController
arguments: ['@ed_blog.article_manager']
tags: ['controller.service_arguments']
Custom Validators Add validation to articles (e.g., minimum word count):
// src/Validator/Constraints/ArticleValidator.php
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ArticleValidator extends ConstraintValidator {
public function validate($article, Constraint $constraint) {
$wordCount = str_word_count($article->getContent());
if ($wordCount < 100) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}
API Endpoints Create a custom API controller to fetch articles:
// src/Controller/Api/ArticleController.php
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ArticleController extends AbstractController {
/**
* @Route("/api/articles", name="api_articles", methods={"GET"})
*/
public function listArticles() {
$articles = $this->getDoctrine()->getRepository(Article::class)->findBy([], ['publishedAt' => 'DESC']);
return $this->json($articles);
}
}
framework.default_locale and framework.timezone are set in .env to avoid datetime issues.php bin/console cache:warmup after extending templates or services.# config/packages/twig.yaml
twig:
strict_variables: true
globals:
ed_blog_asset_version: '1.0'
How can I help you explore Laravel packages today?