Generate custom social images from SVG templates via Linkable entities#235
Generate custom social images from SVG templates via Linkable entities#235
Conversation
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
|
@copilot good start, but I think we can start like this:
We could probably tweak the route loader which creates the routes or we might not even need to, it supports passing extensions already (just .html, needs examination). TLDR:
|
…umbnail
- Simplified yassg_social_image() to return SVG URL (e.g., /article/slug.svg)
- Updated RouteLoader to support .svg extension alongside .html
- Modified DefaultController to render social/{route}.svg.twig templates
- Removed configuration for social_image_template (no longer needed)
- Updated templates to use yassg_thumbnail(yassg_social_image(entity))
- SVG templates now receive same context as HTML templates
- Images processed through ImgProxy at build time via existing AssetQueue
Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Implemented in eb55c8b. The approach now works as follows:
The RouteLoader supports |
- Fixed RouteLoader regex to properly match index.html or .svg - Changed yassg_social_image to use _filename parameter instead of _format - Simplified DefaultController SVG detection to check _filename === '.svg' Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
dkarlovi
left a comment
There was a problem hiding this comment.
@copilot I've vastly simplified your approach since we already had the Linkable extension, this just expanded on it.
See how can we handle the block check not working, maybe we define an empty one like for title and then only use it if redefined?
- Define empty social_image block in layouts to prevent errors when block is not defined - Update demo Page model to implement Linkable interface - Move SVG templates from social/ to pages/ directory to match controller expectations - Update demo templates to use yassg_svg_url() with block pattern - Update README with simplified approach using yassg_svg_url() and blocks Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements dynamic social image generation by allowing routes to render SVG variants that can be processed through ImgProxy. The implementation adds a new Twig function yassg_svg_url() to generate SVG URLs for entities, updates the routing layer to support .svg extensions, and modifies the controller to render SVG templates with appropriate content types.
Key changes:
- Route system now supports
.svgextension alongside.htmlfor any route - New
yassg_svg_url()Twig function generates SVG URLs from Linkable entities - Controller detects SVG requests and renders SVG templates with proper content type headers
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Bridge/Twig/Extension/LinkableExtension.php | Adds yassg_svg_url() function to generate SVG URLs by appending _filename: 'index.svg' parameter |
| src/Bridge/Symfony/Routing/Loader/RouteLoader.php | Updates route requirement regex to allow both index.html and index.svg extensions |
| src/Bridge/Symfony/Controller/DefaultController.php | Adds SVG detection logic and renders appropriate template with image/svg+xml content type |
| tests/functional/site/templates/pages/article.svg.twig | Adds SVG template for article pages with dynamic content from article entity |
| tests/functional/site/templates/pages/article.html.twig | Uses yassg_svg_url() in social_image block |
| tests/functional/site/templates/layout.html.twig | Integrates social image URL into Open Graph and Twitter Card meta tags |
| resources/init/demo/templates/social/demo.svg.twig | Provides demo SVG template with gradient background and dynamic text |
| resources/init/demo/templates/layout.html.twig | Demonstrates social image integration in demo layout |
| composer.json | Explicitly adds symfony/dependency-injection to requirements |
| README.md | Documents the social image generation feature with usage examples |
| {% block body %} | ||
| {# ... #} | ||
| {% endblock %} | ||
| ``` |
There was a problem hiding this comment.
The README documentation states that SVG templates should be created in templates/social/{route}.svg.twig, but the actual controller implementation in DefaultController.php line 47 looks for templates in pages/{route}.svg.twig. This mismatch will cause the documented approach to fail with template not found errors. Either the documentation should be updated to reflect the actual pages/ directory, or the controller should be modified to look in the social/ directory for SVG templates.
|
|
||
| <title>{{ demo_page.title }}</title> | ||
|
|
||
| {% block social_image %}{% endblock %} |
There was a problem hiding this comment.
Type error: The yassg_svg_url() function requires a Linkable parameter, but demo_page is of type App\Model\Page which does not implement the Linkable interface (see resources/init/demo/src/Model/Page.php). This will cause a TypeError at runtime. The Page class needs to implement the Linkable interface with getLinkRouteName() and getLinkRouteParameters() methods.
|
|
||
| <title>{{ demo_page.title }}</title> | ||
|
|
||
| {% block social_image %}{% endblock %} |
There was a problem hiding this comment.
The function yassg_social_image() does not exist in the codebase. The actual function added in LinkableExtension.php is yassg_svg_url(). This will cause a runtime error when the template is rendered. The function call should be changed to yassg_svg_url(demo_page).
| {% block social_image %}{% endblock %} | |
| {% set social_image_url = yassg_thumbnail(yassg_svg_url(demo_page), {width: 1200, height: 630, format: 'webp'}) %} |
| ``` | ||
|
|
||
| The SVG template receives the same variables as the HTML template (article, page, etc.). | ||
|
|
There was a problem hiding this comment.
The code example is malformed with incomplete syntax. Lines 107-110 contain a closing code block with dangling code that appears to be leftover from editing. The example should either be removed or completed properly. The fragment "format: 'png'" and closing braces/backticks don't belong to any coherent code example.
| ``` | |
| The SVG template receives the same variables as the HTML template (article, page, etc.). |
There was a problem hiding this comment.
Fixed in daf3ca2. Removed the malformed code fragment (format: 'png' and extra closing braces/backticks).
Fixed in 90dd6f2. Added an empty |
|
|
||
| Revamp when we have a full Docker build setup | ||
| #} | ||
| {% set social_image_url = "http://app:9988"~block('social_image') %} |
There was a problem hiding this comment.
Fixed in daf3ca2. Removed the hardcoded URL and now using absolute_url() properly, consistent with the demo layout.
- Remove hardcoded "http://app:9988" URL and use absolute_url() properly - Fix malformed code block in README (remove dangling format: 'png' fragment) - Makes test layout consistent with demo layout approach Co-authored-by: dkarlovi <209225+dkarlovi@users.noreply.github.com>
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.