Skip to content

Latest commit

 

History

History
361 lines (291 loc) · 15.3 KB

File metadata and controls

361 lines (291 loc) · 15.3 KB

Configuration

All options live under the root key nowo_blog_kit.

Table of contents

Full YAML tree

nowo_blog_kit:
    user_class: null
    default_locale: es
    locales: [es, en]
    security:
        access_roles: [ROLE_ADMIN]
        manage_roles: [ROLE_EDITOR]
        moderate_roles: [ROLE_MODERATOR]
        configure_roles: [ROLE_ADMIN]
        access_checker: null
        allow_unauthenticated: false
        object_access:
            strategy: none
            service: null
    web_ui:
        layout_template: '@NowoBlogKitBundle/admin/layout.html.twig'
        public_layout_template: '@NowoBlogKitBundle/public/layout.html.twig'
        css_framework: bootstrap5
        icon_set: bootstrap-icons
        row_actions_display: icon
        page_size: 20
        privacy_url: '#'
    listing:
        mode: paginated
        masonry:
            strategy: masonry
            columns_mobile: 1
            columns_tablet: 2
            columns_desktop: 2
    comments:
        rate_limit:
            strategy: fixed_window
            limit: 5
            interval_seconds: 60
            service: null
        captcha:
            strategy: honeypot
            site_key: ''
            secret_key: ''
            min_score: 0.5
            honeypot_field: website
            service: null
    html:
        sanitize:
            strategy: none
            service: null
    doctrine:
        table_prefix: ''
        connection: default

Top-level options

Key Type Default Description
user_class string|null null FQCN of the host user entity implementing BlogUserInterface. Required for Doctrine resolve_target_entities.
default_locale string es Default locale used for translation fallback and BlogLocales.
locales list [es, en] Locales exposed to admin translation forms and public fallback.
security map see YAML Access control for manage / moderate / configure routes.
web_ui map see YAML Admin and public shells, CSS framework, pagination, privacy URL.
doctrine map see YAML Bundle table prefixing and connection name.

This bundle uses a single configuration tree. It does not expose default_profile / profiles of its own. FormKit profiles used by admin filters are documented below.

security

Key Default Description
access_roles [ROLE_ADMIN] Canonical REQ-UI-002 key. Any matching role grants all admin capabilities (manage, moderate, configure). Empty list adds no extra grant.
manage_roles [ROLE_EDITOR] Article and tag admin access (admin_blog except comments/settings).
moderate_roles [ROLE_MODERATOR] Comment moderation (admin_blog_comments*). Editors with manage_roles also moderate.
configure_roles [ROLE_ADMIN] Settings screen (admin_blog_settings).
access_checker null Optional service id implementing BlogKitAccessCheckerInterface.
allow_unauthenticated false When true, the bundle uses an allow-all checker. Intended only for trusted demos.
object_access.strategy none After roles: none (every granted editor sees all rows), owner (publications scoped to createdBy; configure roles see all), or service.
object_access.service null Service id implementing BlogKitResourceAccessCheckerInterface when strategy: service.

The bundle enforces roles on route names beginning with admin_blog (BlogKitAdminAccessSubscriber). Object checks run in admin controllers via BlogKitAccessDenied (edit/delete/inline, and listing filter for owner / custom services). Twig helpers nowo_blog_kit_can_manage_article(), nowo_blog_kit_can_manage_tag(), and nowo_blog_kit_can_moderate_comment() hide row actions; they are not a substitute for the service.

web_ui

Key Default Description
layout_template @NowoBlogKitBundle/admin/layout.html.twig Base layout used by admin screens. Point this to your own layout to embed the admin UI in host chrome.
public_layout_template @NowoBlogKitBundle/public/layout.html.twig Base layout used by public index and article pages.
css_framework bootstrap5 Host CSS stack. The bundle keeps semantic blog-* markup and remaps buttons via UiKit. Allowed: bootstrap, bootstrap4, bootstrap5, tabler, tailwind, foundation, custom, none. Load the matching framework CSS in the host layout; switching this key MUST NOT require forking page Twig files. Default matches the FrankenPHP demo.
icon_set bootstrap-icons How action glyphs are drawn. Allowed: bootstrap-icons, tabler-icons, ux_icon, svg_inline, none. Prepended to UiKit when the host has not set nowo_ui_kit.icon_set.
row_actions_display icon Admin table row actions: icon, text, or icon_text. Switching this MUST NOT require forking list Twig. Prepended to UiKit when the host has not set nowo_ui_kit.row_actions_display.
page_size 20 Admin list page size (1–200).
privacy_url # URL used in the public comment privacy checkbox label.

listing

Public /blog index. Admin settings can override with inherit (use YAML). Column fields use 0 to keep YAML.

Key Default Description
mode paginated paginated (numbered pages) or infinite (IntersectionObserver loads ?partial=1 card fragments).
masonry.strategy masonry masonry (packed columns), grid (uniform rows), or list (single column).
masonry.columns_mobile 1 Columns below 640px (12). Ignored when strategy is list.
masonry.columns_tablet 2 Columns from 640px (12). Ignored when strategy is list.
masonry.columns_desktop 2 Columns from 960px (13). Ignored when strategy is list.

BlogSettings.per_page (admin) is the page size and the infinite-scroll batch size.

comments

Public POST /blog/{slug}/comments protection. Admin settings (/admin/blog/settings) can override the strategies with inherit meaning “use YAML”. CAPTCHA site_key / secret_key are YAML-only.

comments.rate_limit

Key Default Description
strategy fixed_window none, fixed_window (per IP), per_ip_article, sliding_window, or service.
limit 5 Max posts per interval. 0 disables the limiter.
interval_seconds 60 Window length.
service null Service id implementing BlogCommentRateLimiterInterface when strategy: service.

Requires Symfony cache.app. Without a cache pool, limiting is skipped.

comments.captcha

Key Default Description
strategy honeypot none, honeypot, recaptcha_v2, recaptcha_v3, hcaptcha, turnstile, or service.
site_key '' Public widget key for remote providers.
secret_key '' Server-side verification key.
min_score 0.5 Minimum reCAPTCHA v3 score.
honeypot_field website Hidden field name for the honeypot strategy.
service null Service id implementing BlogCommentCaptchaStrategyInterface when strategy: service.

Remote providers need site_key and secret_key. Missing keys fail closed (form invalid).

html

Key Default Description
sanitize.strategy none none (trusted-editor |raw), strip, allowlist (safe CMS tags + YouTube/Vimeo iframes), or service.
sanitize.service null Service id implementing BlogHtmlSanitizerInterface when strategy: service.

Sanitizing runs on article translation persist and again on public render (before hashtag links / body enhancer).

doctrine

Key Default Description
table_prefix '' Prefix applied to all bundle entity tables through TablePrefixListener.
connection default Connection name recorded in configuration for host alignment.

Example:

nowo_blog_kit:
    doctrine:
        table_prefix: 'tenant_a_'

Twig globals

The bundle Twig extension publishes:

Global Meaning
nowo_blog_kit_layout Active admin layout template
nowo_blog_kit_public_layout Active public layout template
nowo_blog_kit_css_framework Selected CSS framework hint
nowo_blog_kit_default_locale Configured default locale
nowo_blog_kit_locales Configured locales
nowo_blog_kit_privacy_url Privacy policy URL for the comment form
nowo_blog_kit_icon_set Selected icon set
nowo_blog_kit_row_actions_display Selected row-action display mode
nowo_blog_kit_can_manage Whether the current user may manage articles and tags
nowo_blog_kit_can_moderate Whether the current user may moderate comments
nowo_blog_kit_can_configure Whether the current user may edit blog settings

Twig function:

Function Meaning
nowo_blog_kit_container_class() Width wrapper (blog-container) plus container (Bootstrap/Tabler) or grid-container (Foundation). Tailwind / custom / none stay on blog-container only.
nowo_blog_kit_captcha() Active comment CAPTCHA context (strategy, site_key, script_url, widget_class).
nowo_blog_kit_can_manage_article(article) Object-level publication access (after roles).
nowo_blog_kit_can_manage_tag(tag) Object-level tag access.
nowo_blog_kit_can_moderate_comment(comment) Object-level comment moderation access.

FormKit profiles

The extension prepends FormKit profiles when the host has not already defined them:

  • blog_kit — defaults for blog forms (translation_domain: NowoBlogKitBundle)
  • filter — GET list filters (auto_placeholder, no labels)

The extension also prepends FormKit type_map.entitySymfony\Bridge\Doctrine\Form\Type\EntityType so article tag fields resolve. Override nowo_form_kit.type_map in the host if needed.

Override those keys in nowo_form_kit.profiles if you need project-specific form chrome. For Bootstrap 5 hosts, set nowo_form_kit.css_framework: bootstrap (FormKit has no bootstrap5 value), add field_types for checkbox / choice, and register twig.form_themes with @NowoFormKitBundle/form/static_blocks.html.twig then bootstrap_5_layout.html.twig. The FrankenPHP demo does this in demo/symfony8/config/packages/.

Translation overrides

Catalogues ship as NowoBlogKitBundle.{locale}.yaml under src/Resources/translations/ (en, es, it, fr, pt, de, nl).

To override strings in the host application, place the same domain in translations/NowoBlogKitBundle.{locale}.yaml (or XLIFF). Symfony loader order gives the application catalogue precedence for the same domain and locale.

See also USAGE.md and SECURITY.md.

Examples

Role-based editor access:

nowo_blog_kit:
    security:
        access_roles: [ROLE_ADMIN]
        manage_roles: [ROLE_EDITOR, ROLE_ADMIN]
        moderate_roles: [ROLE_MODERATOR, ROLE_ADMIN]
        configure_roles: [ROLE_ADMIN]

Custom access checker service:

nowo_blog_kit:
    security:
        access_checker: App\Security\BlogEditorAccessChecker

Editors only manage their own publications:

nowo_blog_kit:
    security:
        manage_roles: [ROLE_EDITOR]
        configure_roles: [ROLE_ADMIN]
        object_access:
            strategy: owner

Custom object-level rules (teams, workflow, …):

nowo_blog_kit:
    security:
        object_access:
            strategy: service
            service: App\Security\BlogPublicationAccessChecker

Host layout + CSS framework (do not fork page templates):

nowo_blog_kit:
    web_ui:
        layout_template: 'admin/layout.html.twig'   # project chrome (demo FrankenPHP uses this)
        public_layout_template: 'base.html.twig'
        css_framework: bootstrap5   # or: tailwind | foundation | custom
        icon_set: bootstrap-icons
        row_actions_display: icon   # or: text | icon_text
        privacy_url: '/privacy'

Keep stylesheets / javascripts blocks in the host layout. Public pages stack nowo-ui.css + blog.css. Remap look-and-feel with --nowo-blog-* / --color-* (or --nowo-ui-*) instead of copying public/index.html.twig.

If the project content block is not admin / nowo_ui_content / body, use a one-file bridge:

{# templates/admin/nowo_blog_kit_bridge.html.twig #}
{% extends 'admin/layout.html.twig' %}
{% block body %}
    {% block nowo_ui_content %}{% endblock %}
    {% block admin %}{% endblock %}
{% endblock %}
nowo_blog_kit:
    web_ui:
        layout_template: 'admin/nowo_blog_kit_bridge.html.twig'
# Tailwind host (load Tailwind in base.html.twig)
nowo_blog_kit:
    web_ui:
        public_layout_template: 'base.html.twig'
        css_framework: tailwind
        icon_set: none
        row_actions_display: text

# Foundation host
nowo_blog_kit:
    web_ui:
        public_layout_template: 'base.html.twig'
        css_framework: foundation
        icon_set: svg_inline
        row_actions_display: icon_text

# Own CSS: semantic blog-* + nowo-ui-* only
nowo_blog_kit:
    web_ui:
        public_layout_template: 'base.html.twig'
        css_framework: custom
        icon_set: svg_inline
        row_actions_display: text

Public listing (paginator or infinite scroll):

nowo_blog_kit:
    listing:
        mode: infinite   # paginated | infinite
        masonry:
            strategy: masonry   # masonry | grid | list
            columns_mobile: 1
            columns_tablet: 2
            columns_desktop: 2

Comment rate limit + CAPTCHA + HTML sanitizer:

nowo_blog_kit:
    comments:
        rate_limit:
            strategy: per_ip_article
            limit: 3
            interval_seconds: 120
        captcha:
            strategy: recaptcha_v3
            site_key: '%env(BLOG_CAPTCHA_SITE_KEY)%'
            secret_key: '%env(BLOG_CAPTCHA_SECRET_KEY)%'
            min_score: 0.5
    html:
        sanitize:
            strategy: allowlist

Admin pages extend @NowoBlogKitBundle/admin/base.html.twig and public pages extend @NowoBlogKitBundle/public/base.html.twig. Those templates call {{ parent() }} in stylesheets / javascripts and then load nowo_ui_kit + nowo_blog_kit assets inside nested nowo_ui_styles / nowo_ui_scripts (REQ-UI-001). Keep matching stylesheets and javascripts blocks in the host layout so stacking works. Override only those nested blocks if you need extra CSS/JS. Do not fork every CRUD page to inject CSS/JS.

Row actions compose UiKit _row_actions. Switch web_ui.row_actions_display (icon / text / icon_text) without copying list templates. Deletes open a native <dialog> confirm (_delete_confirm.html.twig + UiKit _confirm) with POST + CSRF in the footer. The inline CMS editor is the same native-dialog contract (_modal_form.html.twig). See UiKit ADOPTION and STIMULUS.