Current Account And Routes
One of the most useful parts of account-bundle is not the ready-made screens. It is the current-account flow around the /{_account} route parameter.
Once the account is part of the route, the bundle can resolve it before your controller runs and reuse that context in Twig, access checks, and Doctrine filtering.
Keep _account In The URL
This is the safest route pattern:
YAML
project_list:
path: /account/{_account}/projects
controller: App\Controller\ProjectController::list
PHP
<?php
// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;
return static function (RoutingConfigurator $routes): void {
$routes->add('project_list', '/account/{_account}/projects')
->controller('App\\Controller\\ProjectController::list');
};
route_param_name controls which request attribute the shared context resolver reads. The default _account keeps the examples and bundled routes consistent. The resolver uses find_field_name and reuses an entity already resolved into the attribute.
Building Real Account Areas
The pattern becomes more useful when you apply it to whole areas:
YAML
_provider:
resource: 'routes/provider/*'
prefix: '/{_locale}/provider/{_account}'
_corporate:
resource: 'routes/corporate/*'
prefix: '/{_locale}/corporate/{_account}'
PHP
<?php
// config/routes.php
namespace Symfony\Component\Routing\Loader\Configurator;
return static function (RoutingConfigurator $routes): void {
$routes->import('routes/provider/*')->prefix('/{_locale}/provider/{_account}');
$routes->import('routes/corporate/*')->prefix('/{_locale}/corporate/{_account}');
};
This lets your product areas stay account-aware without repeating account-loading code in every controller.
Request Listener Resolution
AccountRequestListener runs after routing. When the request contains the configured route attribute:
- it reads the raw route value
- it loads the account repository for
AccountInterface - it searches with
find_field_name - it writes the resolved entity back into the request attribute
- it stores the entity in router context
- it injects the entity into Twig as
app.accountby default
That means a route parameter such as /{_account} turns into a real account object before your controller logic starts.
Using The Current Account In Controllers
The simplest pattern is to read the resolved account from the request:
/** @var AccountInterface $account */
$account = $request->attributes->get('_account');
On Symfony versions with ValueResolverInterface, the bundle also registers AccountValueResolver, so controller arguments typed as AccountInterface can be resolved directly:
use Softspring\AccountBundle\Model\AccountInterface;
use Symfony\Component\HttpFoundation\Response;
public function settings(AccountInterface $account): Response
{
// ...
}
The request listener and value resolver share the same context resolver, including find_field_name. Protect the route with a stateful firewall so account access is checked against the authenticated user.
Using The Current Account In Twig
With softspring/twig-extra-bundle installed, templates can use:
{{ app.account.name }}
This is useful for account navigation, headers, breadcrumbs, and account-scoped UI.
Practical Advice
- keep
_accountas the current-account key - use account-aware prefixes early, not only on one page
- validate the design by building one real product area such as projects, provider dashboard, or account settings
- if that first area feels awkward, review the entity model before adding more screens