Extend your Pushword website with comments, a contact form or just an user input.
Via Packagist :
# Get the Bundle
composer require pushword/conversation
That's it ! If you have a custom installation (not used the default installer),you may have a look inside vendor/pushword/admin/install.php.
# Load form via fetch (javascript)
<div data-live="{{ conversation('newsletter') }}"></div>
# =
<div data-live="{{ path('pushword_conversation', {'type': 'newsletter', 'referring': 'newsletter-'~page.slug, 'host': page.host}) }}"></div>
# Render form in Controller
{{ render(controller('Pushword\\Conversation\\Controller\\ConversationFormController::show')) }}
# Or add a button to click before loading block
<button data-src-live="{{ path('pushword_conversation', {'type': 'newsletter', 'referring': 'nslttr-'~page.slug, 'host': page.host}) }}" class="btn btn-primary">Register</button>
# Advanced usage
<p>This is an invitation to <button data-src-live="..." data-target="parent">register</button></p>
Activate the data-live element with @pushword/js-helper :
import { liveForm } from "@pushword/js-helper/src/helpers";
// on dom changed and on page loaded :
liveBlock();
```
{{ showConversation(referring[, orderBy, limit, template]) }}
Configure the bundle directly in app configuration
conversation_notification_email_to: "example@example.tld",
conversation_notification_email_from: "example@example.tld",
conversation_notification_interval: "PT1S" #each 1s, default 1 time per day
By overriding @PushwordConversation/conversation/conversation.html.twig(or '@PushwordConversation/conversation/'.$type.'Step'.$step.'.html.twigor '@PushwordConversation/conversation/'.$type.$referring.'Step'.$step.'.html.twig).
Per default, there are 4 form types: newsletter, message, ms_message and multistep_message.
Add a new class in bundle config pushword_conversation.conversation_form.myNewType: myNewFormClass or at the app level config pushword.apps[...].conversation_form: [...]
When the Flat extension is enabled, every pw:flat:sync run also synchronizes conversation messages with a CSV file.
This allows you to backup or edit conversations alongside pages and medias without needing a database access.
By default, all conversations are stored in a single global file at content/conversation.csv, regardless of host. This simplifies management, especially for single-site installations or when conversations don't need to be separated by host.
You can switch to per-host storage if needed:
# config/packages/pushword.yaml
conversation:
flat_conversation_global: true # (default) Single file: content/conversation.csv
# flat_conversation_global: false # Per-host files: content/<host>/conversation.csv
The host column in the CSV preserves the host information in both modes, allowing filtering or migration between modes.
# Auto-detect import vs export (or force with -f import|export|sync)
php bin/console pw:message:flat [host] [-f sync]
# Import an external CSV without touching local files
php bin/console pw:message:import path/to/conversation.csv [--host=example.com]
Automatically translate reviews to multiple languages using DeepL or Google Cloud Translation APIs.
Add your API keys in the pushword configuration:
# config/packages/pushword.yaml
conversation:
translation_deepl_api_key: '%env(DEEPL_API_KEY)%'
translation_google_api_key: '%env(GOOGLE_API_KEY)%'
translation_deepl_use_free_api: true # Use DeepL free API endpoint
translation_deepl_monthly_limit: 450000 # Monthly char limit (0 = unlimited)
translation_google_monthly_limit: 450000
DeepL is used as the primary service (higher priority). If DeepL's monthly limit is exceeded or unavailable, Google Cloud Translation is used as fallback.
# Translate all reviews to French
php bin/console pw:conversation:translate-reviews --locale=fr
# Translate to multiple locales
php bin/console pw:conversation:translate-reviews --locale=fr,de,es
# Filter by host
php bin/console pw:conversation:translate-reviews --locale=fr --host=example.com
# Force re-translation of existing translations
php bin/console pw:conversation:translate-reviews --locale=fr --force
# Preview without making changes
php bin/console pw:conversation:translate-reviews --locale=fr --dry-run
The command automatically detects the source language of each review. If a review has no locale set, the translation API will detect it and save it for future use.
Translations are automatically displayed based on the current page locale. The review.html.twig template uses page.locale (or app.request.locale as fallback) to show the appropriate translation.
If no translation exists for the requested locale, the original content is displayed.
Character usage is tracked per service per month in the translation_usage database table. When a service exceeds its configured limit, the system automatically falls back to the next available service.
To check current usage:
php bin/console dbal:run-sql "SELECT * FROM translation_usage"