nowo-tech/blog-kit-bundle

Reusable Symfony blog kit: multilingual articles, tags, comments, settings, LinkedIn hashtags, and a secured admin CRUD UI.

Maintainers

Package info

github.com/nowo-tech/BlogKitBundle

Documentation

Type:symfony-bundle

pkg:composer/nowo-tech/blog-kit-bundle

Transparency log

Fund package maintenance!

HecFranco

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-08-18 20:57 UTC

This package is auto-updated.

Last update: 2026-08-18 21:04:17 UTC


README

CI Packagist Version Packagist Downloads License PHP Symfony GitHub stars Coverage

Found this useful? Give it a star on GitHub! It helps us maintain and improve the project.

Reusable Symfony blog kit for multilingual articles, tags, moderated comments, professional listing settings, LinkedIn hashtag sync, and a secured admin CRUD UI composed with UiKit and FormKit.

Compatible with Symfony 7.4+ and 8.x on PHP 8.4+

FrankenPHP Friendly Worker Mode

This bundle is FrankenPHP worker mode friendly.

What is this?

Blog Kit Bundle gives Symfony applications a reusable blog domain backed by Doctrine. Editors manage articles, tags, and settings in a secured admin UI. Visitors browse a public index and article pages, search and filter by tag, and submit comments that wait for moderation. Hosts can hook BlogArticlePublishedEvent (for example Web Push) and sync trailing LinkedIn hashtags into tags.

Features

  • Multilingual articles and tags with locale fallback (es, en by default)
  • Public index and article routes at /blog and /blog/{slug}
  • Moderated comments with staff replies, configurable rate limits, and CAPTCHA strategies
  • Optional article HTML sanitizer (none, strip, allowlist, or a host service)
  • Admin CRUD for articles, tags, comments, and singleton blog settings
  • Paginated or infinite-scroll listing, configurable asides, and card options
  • LinkedIn hashtag formatting command nowo:blog:sync-hashtags
  • BlogArticlePublishedEvent after an article becomes published
  • Configurable access: access_roles, manage / moderate / configure roles, custom access_checker, and object-level publication rules (security.object_access: none / owner / host service) via BlogKitAccessDenied
  • Host CSS stack via web_ui.css_framework (bootstrap5, tailwind, foundation, custom), icon_set, and row_actions_display without forking page templates
  • Twig namespace NowoBlogKitBundle with host override precedence
  • Symfony Flex recipe and FrankenPHP demo in demo/symfony8

Quick start

composer require nowo-tech/blog-kit-bundle
composer require twig/extra-bundle twig/string-extra
# config/packages/nowo_blog_kit.yaml
nowo_blog_kit:
    user_class: App\Entity\User
    default_locale: es
    locales: [es, en]
    security:
        access_roles: [ROLE_ADMIN]
        manage_roles: [ROLE_EDITOR]
        moderate_roles: [ROLE_MODERATOR]
        configure_roles: [ROLE_ADMIN]
        allow_unauthenticated: false
        # object_access:
        #     strategy: owner
    web_ui:
        layout_template: admin/layout.html.twig
        public_layout_template: base.html.twig
        css_framework: bootstrap5
        icon_set: bootstrap-icons
        row_actions_display: icon
# config/routes/nowo_blog_kit.yaml
nowo_blog_kit:
    resource: '@NowoBlogKitBundle/Resources/config/routing.yaml'
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

Public blog: /blog. Admin: /admin/blog, /admin/blog/tags, /admin/blog/comments, /admin/blog/settings.

Development

make up
make test
make phpstan
make -C demo/symfony8 up
make demo-smoke

Demo default URL: http://localhost:8105.

Documentation

Additional documentation

Tests and coverage

Area Status Command
PHP src/ coverage target 100% make test-coverage-100
TS/JS src/Resources/assets ≥90% make test-ts
Unit and bundle QA Enabled make test
Full release checks Enabled make release-check
  • PHP: 100%
  • TS/JS: 100%
  • Python: N/A
make test
make test-coverage
make test-coverage-100
make test-ts
make assets
make release-check

License

MIT — see LICENSE.