Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blog Bundle Laravel Package

polishsymfonycommunity/blog-bundle

A Symfony bundle from the Polish Symfony Community for adding a blog to your application, with straightforward post management and integration into existing Symfony projects to help you publish and organize articles quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle maps an existing WordPress database onto Doctrine entities so a Symfony app can render blog content that editors still manage in wp-admin. It is archived and has zero dependents, so treat it as a starting point you will fork and own, not a maintained dependency.

Minimal setup:

  1. composer require polishsymfonycommunity/blog-bundle (or vendor the repo and add a repositories entry — the archived state makes the Packagist route fragile). Check composer.json for the PHP/Symfony constraints; it targets the Symfony 2/3 era, so on modern Symfony you will likely need to bump constraints and fix deprecations before it boots.
  2. Register the bundle: new PolishSymfonyCommunity\BlogBundle\PSSBlogBundle() in AppKernel, or add it to config/bundles.php.
  3. Point it at the WordPress database. Do not reuse your app's default connection. Define a second Doctrine connection (doctrine.dbal.wp_connection) with the WordPress credentials, and configure the bundle to use it along with your table prefix:
pss_blog:
    connection: wp_connection
    table_prefix: wp_   # change for installs using a custom prefix
  1. Verify the mapping: php bin/console doctrine:mapping:info --em=wp should list Post, Comment, Term/Tag/Category, and User entities. If it is empty, the bundle was not registered or the EM name is wrong.

Where to look first: the bundle's Entity/ directory (the canonical list of what fields you actually get), then Resources/config/ for the service IDs and the ORM mapping, then the controllers for the assumed routing. The README is thin — the mapping files are the real documentation.

First use case: a read-only blog index plus a single-post page. Wire /blog to the post repository filtered to published posts, paginate, and /blog/{slug} to a findOneBySlug-style lookup. Comments and taxonomy archives can come later.

Implementation Patterns

Separate entity manager, read-mostly. The cleanest integration is a dedicated wp entity manager so the bundle's entities never leak into your app's schema and doctrine:schema:update can never touch WordPress tables. Point the bundle's services at that EM and keep your domain entities on the default one.

Repository-driven controllers. The bundle's repositories are the intended entry point. Typical query shape for an index page:

$posts = $postRepository->createPublishedQueryBuilder()
    ->orderBy('p.postDate', 'DESC')
    ->setMaxResults($limit)
    ->setFirstResult($offset)
    ->getQuery()
    ->getResult();

Filter explicitly — WordPress stores pages, attachments, revisions, and auto-drafts in the same wp_posts table.

Taxonomy rendering. Tags and categories live in wp_terms joined through wp_term_taxonomy and wp_term_relationships. Build archive routes (/tag/{slug}, /category/{slug}) against the term repository, and render the term's count for "N posts" labels.

Comments as a second-class citizen. Reading approved comments is trivial; writing them means inserting into wp_comments with correct comment_approved, comment_agent, and comment_parent values, or editors will not see them in wp-admin. Prefer proxying writes back through WordPress (a small REST call or WP-CLI invocation) if comment volume matters, and only render the read side from Symfony.

Caching is the integration contract. WordPress writes bypass Doctrine's identity map and any second-level cache, so cache rendered fragments with a short TTL (or purge via a webhook from WordPress) rather than caching entities indefinitely.

Hybrid deployment. The pattern that actually works long-term: WordPress stays the editorial back end on its own host, Symfony owns the public front end and SEO surface. Keep the WP database connection read-only at the MySQL user level for the Symfony app, and give the comment-proxy service the only write credentials.

Overriding presentation. Copy the bundle's Twig templates into templates/bundles/PSSBlogBundle/ and edit there; do not patch vendor code for styling. Decorate repositories in services.yaml if you need extra query methods rather than editing the bundle's classes.

Gotchas and Tips

  • post_status and post_type are not optional filters. Without post_status = 'publish' and post_type = 'post' you will render drafts, revisions, menus, and media attachments. Password-protected posts (post_password != '') need a separate guard.
  • Two sets of dates. post_date is site-local; post_date_gmt is UTC. Use the GMT column for ordering and formatting in Symfony, or timezone drift will scramble your archive.
  • Serialized data lurks in wp_postmeta and wp_options. Any meta value is a PHP-serialized blob until proven otherwise; unserialize() with allowed_classes => false, or parse with a JSON-first fallback. Do not assume meta_value is a string.
  • Content is unfiltered WordPress HTML. post_content contains shortcodes, <!--more--> markers, and block comments. Either render raw and accept broken shortcodes, or strip/transform them in a Twig extension. Escape nothing you did not generate yourself, but sanitize before output if untrusted authors exist.
  • Excerpts may be empty. WordPress generates excerpts on the fly; the stored post_excerpt is often blank. Fall back to a truncated, tag-stripped post_content.
  • Never run schema tooling against this connection. No doctrine:schema:update, no migrations. The mapping is descriptive, not authoritative — WordPress owns the schema.
  • Multisite installs use per-site prefixes (wp_2_, wp_3_). The single table_prefix config cannot express that; you need one connection/config per site or a runtime-switched prefix.
  • Comment threading relies on comment_parent; build the tree yourself (comment_approved = '1', parent 0 roots) rather than assuming the bundle returns nested objects.
  • Performance: WordPress indexes are tuned for wp-admin, not your queries. Slug lookups on post_name and joins through term_relationships can be slow on large sites — add read-replica indexes if you cannot cache.
  • The bundle is archived. Pin it, fork it into your VCS, and expect to fix Symfony deprecations yourself. Budget for that on day one; there will be no upstream fixes, and the low star count means no community answers either.
  • Extension points worth using: template override directory, repository service decoration, and the second-connection config. Everything else — entities, mapping, controllers — is safer to copy into your app than to extend.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr