Integrate Symfony with Storyblok
Use Storyblok to manage the content of your website built with Symfony.
Create a new Symfony project by following the official installation manual.
If you already have a Storyblok account, log into app.storyblok.com or log in with GitHub to continue.
Create a new blank space to follow the tutorial from scratch.
Installation
Section titled “Installation”In the terminal, cd into your Symfony project and install the Storyblok packages.
composer require storyblok/php-content-api-client storyblok/symfony-bundleIn the root of your project, create a .env file with the access token of your space.
###> storyblok/symfony-bundle ###STORYBLOK_API_BASE_URI=https://api.storyblok.comSTORYBLOK_API_TOKEN=your_storyblok_api_tokenSTORYBLOK_VERSION=published # the bundle's default###< storyblok/symfony-bundle ###Fetch a single story
Section titled “Fetch a single story”Create a Page content type to fetch and render all stories of the page content type.
<?php
declare(strict_types=1);
namespace App\ContentType;
use Storyblok\Bundle\ContentType\ContentType;
final readonly class Page extends ContentType{ public string $uuid; public string $name; public string $slug; public array $body; public \DateTimeImmutable $publishedAt;
public function __construct(array $values) { $this->uuid = $values['uuid']; $this->name = $values['name']; $this->slug = $values['full_slug']; $this->body = $values['content']['body'] ?? []; $this->publishedAt = new \DateTimeImmutable($values['published_at']); }
public function publishedAt(): \DateTimeImmutable { return $this->publishedAt; }}Next, create a controller for this content type.
<?php
declare(strict_types=1);
namespace App\Controller;
use App\ContentType\Page;use Storyblok\Bundle\ContentType\Attribute\AsContentTypeController;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;
#[AsContentTypeController(contentType: Page::class)]final class PageController extends AbstractController{ public function __invoke(Request $request, Page $page): Response { return $this->render('page.html.twig', [ 'page' => $page, ]); }}The #[AsContentTypeController] attribute automatically registers the controller to handle requests for the specified content type.
Finally, add Twig templates for rendering. Start with the base layout:
<!DOCTYPE html><html> <head> <meta charset="UTF-8"><title>{% block title %}Welcome to Storyblok!{% endblock %}</title>
{% block stylesheets %} {% endblock %} {% block javascripts %} {% endblock %} </head> <body> <div class="container"> {% block body %}{% endblock %} </div> </body></html>Then, create a template to render the page content type:
{% extends 'base.html.twig' %}
{% block body %} {% if page.body is defined and page.body is not empty %} {% for block in page.body %} {% if block is not null %} {{ block|render_block }} {% endif %} {% endfor %} {% endif %}{% endblock %}The render_block Twig filter automatically renders blocks using their registered templates.
Create blocks and templates
Section titled “Create blocks and templates”Stories usually contain a body or similar field that consists of an array with several custom type blocks (for example, Feature, Teaser, Grid).
Create them as follows:
<?php
declare(strict_types=1);
namespace App\Block;
use Storyblok\Bundle\Block\Attribute\AsBlock;
#[AsBlock]final readonly class Feature{ public string $name;
public function __construct(array $values) { $this->name = $values['name'] ?? ''; }}<?php
declare(strict_types=1);
namespace App\Block;
use Storyblok\Bundle\Block\Attribute\AsBlock;
#[AsBlock]final readonly class Teaser{ public string $headline;
public function __construct(array $values) { $this->headline = $values['headline'] ?? ''; }}<?php
declare(strict_types=1);
namespace App\Block;
use Storyblok\Bundle\Block\Attribute\AsBlock;
#[AsBlock]final readonly class Grid{ public array $columns;
public function __construct(array $values) { $this->columns = $values['columns'] ?? []; }}The #[AsBlock] attribute automatically registers blocks for rendering. The bundle defaults to block templates stored in templates/blocks/{name}.html.twig.
Create them as follows:
<div class="feature"> <span>{{ block.name }}</span></div><div class="teaser"> <h2>{{ block.headline }}</h2></div><div class="grid"> {% for column in block.columns %} <div> {{ column|render_block }} </div> {% endfor %}</div>Similar to the Page template, the Grid template iterates over the columns block field and renders nested blocks.
In Storyblok, open Content, select the Home story, and publish it.
Run the Symfony development server and open http://localhost:8000/home in the browser.
symfony server:startWas this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy. Terms of Service apply.
Get in touch with the Storyblok community