## Getting Started
### Minimal Setup
1. **Installation**
Add the bundle via Composer:
```bash
composer require austral/website-bundle
Register the bundle in config/bundles.php:
Austral\WebsiteBundle\AustralWebsiteBundle::class => ['all' => true],
Publish Configuration Publish the default config:
php artisan austral:website:install
This generates:
database/migrations/...)config/routes/website.php)resources/lang/)First Use Case: Create a Website
Define a website in config/website.php:
'websites' => [
'main' => [
'domain' => 'example.com',
'default_language' => 'en',
'redirects' => [
'old-site.com' => '/new-path',
],
],
],
Run migrations:
php artisan migrate
Basic Routing
Use the website() helper in routes:
// routes/website.php
website()->get('/', 'PageController@home');
website()->domain() middleware to route requests based on the domain:
Route::domain('{domain}')->group(function () {
website()->matchDomain('blog.example.com')->get('/', 'BlogController@index');
});
config/website.php:
'fallbacks' => [
'example.com' => 'www.example.com',
],
entity-translate-bundle for language-aware content:
use Austral\EntityTranslateBundle\Traits\Translatable;
class Page
{
use Translatable;
}
$url = website()->generateUrl('page.show', ['id' => 1], 'fr');
seo-bundle with the website context:
$meta = website()->getSeoService()->generateMeta('page.title', 'page.description');
php artisan austral:seo:sitemap:generate --website=main
content-block-bundle) and embed them:
{{ austral_content_block('header') }}
$file = website()->getFileService()->upload('logo.png', 'websites/main');
AppServiceProvider:
public function register()
{
$this->app->extend('website', function ($website) {
$website->setCustomConfig(['key' => 'value']);
return $website;
});
}
WebsiteCreated):
Event::listen(WebsiteEvents::CREATED, function ($website) {
Log::info("Website {$website->getName()} created.");
});
routes/admin.php:
website()->admin()->get('/websites', 'WebsiteController@index');
namespace App\Console\Commands;
use Austral\WebsiteBundle\Console\WebsiteCommand;
class CustomWebsiteCommand extends WebsiteCommand
{
protected $signature = 'austral:website:custom {action}';
// ...
}
Domain Configuration
HTTP_HOST header is missing (e.g., in tests).
Fix: Mock the Request object or use website()->setTestDomain('test.example.com').website()->domain() middleware is registered before other domain-based routes.Language Defaults
config/website.php and run:
php artisan austral:website:update-defaults
SEO Bundle Dependency
seo-bundle config if not installed.
Fix: Install it first:
composer require austral/seo-bundle
File Storage
entity-file-bundle may not respect website-specific paths.
Fix: Use the website-aware service:
$path = website()->getFileService()->getPath('logo.png', 'websites/main');
Caching
$this->addCacheTags(['website:main']);
Log Website Context
Add this to your AppServiceProvider to log the current website:
public function boot()
{
if ($this->app->has('website')) {
$this->app->booted(function () {
\Log::debug('Current website:', [
'name' => website()->getName(),
'domain' => website()->getDomain(),
]);
});
}
}
Check Middleware Order
Ensure website() middleware is registered after locale() but before web:
$middlewareGroups['web'] = [
// ...
\Austral\WebsiteBundle\Http\Middleware\WebsiteMiddleware::class,
// ...
];
Validate Config
Use the validate command to check your config/website.php:
php artisan austral:website:validate
Custom Website Entities
Extend the base Website entity:
namespace App\Entity;
use Austral\WebsiteBundle\Entity\Website as BaseWebsite;
class Website extends BaseWebsite
{
#[ORM\Column]
private ?string $customField = null;
// Add getters/setters
}
Update the bundle’s WebsiteType in your AppWebsiteBundle.
Override Templates
Copy the bundle’s Twig templates to resources/views/austral/website/ to override them.
Add Custom Fields
Use the entity-translate-bundle to add translatable fields to Page or ContentBlock:
#[ORM\Column]
#[Assert\NotBlank]
private ?string $customTitle = null;
Hook into Redirects Extend the redirect logic in a service:
namespace App\Service;
use Austral\WebsiteBundle\Service\WebsiteRedirectService;
class CustomWebsiteRedirectService extends WebsiteRedirectService
{
public function getRedirects(): array
{
$redirects = parent::getRedirects();
$redirects['custom.com'] = '/custom-path';
return $redirects;
}
}
Bind it in config/services.yaml:
services:
Austral\WebsiteBundle\Service\WebsiteRedirectService: '@App\Service\CustomWebsiteRedirectService'
Custom Commands
Extend existing commands (e.g., WebsiteCommand) to add functionality:
namespace App\Console\Commands;
use Austral\WebsiteBundle\Console\WebsiteCommand;
class BackupWebsiteCommand extends WebsiteCommand
{
protected $signature = 'austral:website:backup {website}';
protected $description = 'Backup a website\'s content';
public function handle()
{
$website = $this->getWebsite($this->argument('website'));
// Add backup logic
}
}
Cache Website Lookups
Cache the website resolver in WebsiteMiddleware:
$website = Cache::remember("website.{$request->getHost()}", 3600, function () use ($request) {
return website()->findByDomain($request->getHost());
});
Lazy-Load SEO Data Defer SEO data loading until needed:
$seoService = website()->get
How can I help you explore Laravel packages today?