Installation:
composer require alpixel/seobundle
Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3/2):
Alpixel\Bundle\SEOBundle\SEOBundle::class => ['all' => true],
Database Migration:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
(Note: The package expects a seo_metatag table; verify schema compatibility.)
First Use Case:
config/packages/alpixel_seo.yaml:
alpixel_seo:
sitemap:
enabled: true
routes: ['app_homepage', 'app_blog_post']
use Alpixel\Bundle\SEOBundle\Annotation\MetaTag;
/**
* @Route("/blog/{slug}", name="app_blog_post")
* @MetaTag("blog_post", providerClass="App\Entity\Post", title="Blog Post: {post:title}")
*/
public function showPost(Post $post) { ... }
Dynamic Meta Tags:
MetaTagPlaceholderInterface in your entity:
class Post implements MetaTagPlaceholderInterface {
public function getPlaceholders(): array {
return [
'[post:title]' => $this->title,
'[post:description]' => substr($this->content, 0, 160),
];
}
}
@MetaTag on controllers to link entities to routes:
@MetaTag("product", providerClass="App\Entity\Product", title="Product: {product:name}")
php bin/console alpixel:seo:metatag:dump to sync annotations to the DB. Manage patterns via the SonataAdmin panel (if integrated).Sitemap Generation:
Alpixel\Bundle\SEOBundle\Sitemap\Provider\RouteProvider to add logic (e.g., exclude draft content)./sitemap.xml (default route).Static Meta Tags:
Twig or Meta components for static tags.)SEOManager:
public function __construct(private SEOManager $seoManager) {}
{% block meta %}
<title>{{ app.seo.getTitle() }}</title>
<meta name="description" content="{{ app.seo.getDescription() }}">
{% endblock %}
.htaccess or symfony/webpack-encore:
<FilesMatch "\.xml$">
Header set Cache-Control "public, max-age=3600"
</FilesMatch>
Database Schema:
seo_metatag table. If migrations fail, manually create it or adjust the schema.php bin/console alpixel:seo:metatag:dump after schema updates.Annotation Registration:
alpixel:seo:metatag:dump after adding @MetaTag annotations will break meta tag generation.composer.json:
"scripts": {
"post-install-cmd": [
"php bin/console alpixel:seo:metatag:dump"
]
}
Sitemap Routes:
/blog/post not /blog?post=123). Use requirements in routes.yaml to enforce this./sitemap.xml or enable debug mode:
alpixel_seo:
sitemap:
debug: true
Placeholder Conflicts:
[post:title] in multiple entities) will overwrite values. Use unique prefixes like [blog_post:title].getPlaceholders():
if (empty($this->title)) {
throw new \RuntimeException("Title required for SEO placeholders.");
}
Log Meta Tags: Enable debug mode in config/packages/dev/alpixel_seo.yaml:
alpixel_seo:
debug: true
Logs will appear in var/log/dev.log.
Check Annotations:
php bin/console debug:container alpixel.seo.annotation_reader
Verify annotations are loaded.
Custom Providers:
Alpixel\Bundle\SEOBundle\Sitemap\Provider\AbstractProvider to add logic (e.g., priority scoring):
class CustomPriorityProvider extends AbstractProvider {
public function getPriority(): float {
return $this->isFeatured() ? 1.0 : 0.5;
}
}
services.yaml:
services:
App\Sitemap\CustomPriorityProvider:
tags: ['alpixel.seo.sitemap.provider']
Override Templates:
templates/SEOBundle/Sitemap/sitemap.xml.twig to templates/SEOBundle/Sitemap/ to customize sitemap structure.Event Listeners:
seo.metatag.pre_generate to modify tags dynamically:
use Alpixel\Bundle\SEOBundle\Event\MetaTagEvent;
public function onMetaTagGenerate(MetaTagEvent $event) {
$event->setTitle("Promo: " . $event->getTitle());
}
Register as a service with the kernel.event_listener tag.alpixel_seo:
admin:
enabled: false
presta/sitemap-bundle (v1.5). Conflicts may arise with newer versions. Pin the dependency in composer.json:
"presta/sitemap-bundle": "1.5.0"
How can I help you explore Laravel packages today?