Chapters
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Hey everyone! Welcome to 30 days of LAST Stack! I gotta say, this might be my favorite tutorial ever. I had an absolute blast building this, because unlike usual around here, I'm going to go a little bit less into teaching deep concepts and instead focus on making a rich, polished, beautiful product. And I think you're going to love it.
But first, LAST Stack, what the heck is that? It's an acronym that... I made up. I wanted something fun to match a whole new paradigm. It stands for Live Components, AssetMapper, Stimulus, and Turbo. It's a front-end stack that'll let us build a truly rich user interface - like a single-page application, with modals and AJAX everywhere - but entirely with Symfony, Twig... and just a bit of JavaScript. Oh, and this will require no build step and no Node.js. Woo!
By the end of this tutorial, we're going to have reusable patterns that we can leverage in on our projects to get things done really quickly but that work and feel incredible.
At the core of this whole system is Hotwire: a collection of libraries that include Turbo, Stimulus and Strada. Strada is the new kid on the block and it looks cool. We won't have time to talk about it, but it promises to let you take the same project that we're about to build and use it to power a mobile app. Woh.
One other cool things about Hotwire is that... it's not unique to Symfony. It's used, for example, by the Ruby on Rails community. And many of the things that we're going to build come from patterns I learned from people in that community. The fact that we're all using the same tool means we get to share libraries, share ideas and build on top of each other's shoulders. That's massive.
Project Setup
So let's get into this! Because it's fun to make pretty things that pop onto the screen, you should absolutely download the course code and code along with me. When you unzip the file, you'll find a start/
directory, which has the same files that you see here, including the all-important README.md! This tells you all about how to get the project set up.
The last step will be to open a terminal, move into the project, and run:
symfony serve -d
To start a local web server at ... oh, in my case, 127.0.0.1:8001
. I must already have something running on port 8000. I'll click the link to see a big, ugly page of... nothing! That's on purpose!
What we're starting with is a Symfony 6.4 project. I've pre-installed Twig and we have two different entities - Planet
and Voyage
- because we're going to build a trip-planning site for aliens. I also have some data fixtures and I used MakerBundle to generate a CRUD for each entity. This PlanetController
, VoyageController
and these templates come from MakerBundle, with just a few styling adjustments.
But basically... there's nothing special going on! We do have a MainController
, which powers this homepage:
Show Lines
|
// ... lines 1 - 12 |
class MainController extends AbstractController | |
{ | |
#[Route('/', name: 'app_homepage')] | |
public function homepage( | |
VoyageRepository $voyageRepository, | |
PlanetRepository $planetRepository, | |
#[MapQueryParameter('query')] string $query = null, | |
#[MapQueryParameter('planets', \FILTER_VALIDATE_INT)] array $searchPlanets = [], | |
): Response | |
{ | |
$voyages = $voyageRepository->findBySearch($query, $searchPlanets); | |
return $this->render('main/homepage.html.twig', [ | |
'voyages' => $voyages, | |
'planets' => $planetRepository->findAll(), | |
'searchPlanets' => $searchPlanets, | |
]); | |
} | |
} |
It contains a query that will help us later... but the template, right now, is doing a whole lot of nothing:
{% extends 'base.html.twig' %} | |
{% block title %}Space Inviters!{% endblock %} | |
{% block body %} | |
<h1>Space Inviters: Plan your voyage and come in peace!</h1> | |
{% endblock %} |
No CSS, no JavaScript, no assets of any kind... and the site doesn't do anything. But in 30 short lessons, we'll transform this into a small digital masterpiece.
That's it for day 1. Tomorrow, we'll install AssetMapper: a system for handling CSS, JavaScript and other frontend assets with batteries include... but absolutely no build step.
23 Comments
Cool! Thank you for sharing it @Adn-B
Hello guys, I'd like just to post here so it might help. I followed to readme but I had error trying to connect with the database. As Ryan posted in other comments execute symfony var:export --multiline
to check if DATABASE vars are exported and they werent.
I'm running Windows 10 with Composer setup installed and Wamp with php versions 7.x and 8.x. I was able to solve the problem uninstalling composer. It seems as some how the default php version defined when installing composer was messingup symfony cli.
See ya, and keep up the good work.
Thanks for the hint @donwilson. I'm running Mac Sonoma on an M1 pro and had the same problem (missing DATABASE vars). For me the problem wasn't composer conflicting with the Symfony binary it was that in this project (and I believe newer docker compose projects) the compose file is named 'compose.yaml' and I think Symfony CLI hasn't caught up yet because once I changed this to docker-compose.yaml and reserved the app using 'symfony serve' the DATABASE vars were exported and everything works as expected. I hope this helps someone else on a Mac if they have this problem.
Nice catch !! I haven't noticed that change.. Thanks for adding up !
Hey @skofield!
Ah, that makes sense! The project DOES come with the newer compose.yaml
file (formerly docker-compose.yaml
. The latest symfony
binary does support this, but it was added only in a recent version - it was in version 5.6.2 released in late October 2023.
This will probably trip up a few people - so I'm happy to have the conversation here!
Cheers!
Yes!.. with all the tooling one has to handle per project is easy to forget to check if everything is up to date, not to mention to stay up date with all the changes.
Thanks @weaverryan.
Hey @donwilson!
Thanks for posting the steps that unlocked you! And if anyone else has problems with the database connection, you can always go into .env
and change the DATABASE_URL
to use sqlite. It's not as fancy as Postgres, but sqlite is great and will work awesome for the tutorial :).
Cheers!
You are welcome Ryan.
Oh! That's a golden tip there, especially for newcomers. Maybe that line can be included in the Readme file?. I think it might be helpful.
Best regards.
Good idea - let me check into that :)
Hi All,
PROB
I have an issue. Symfony is no longer loading my Docker variables.
I often run a "docker-compose up -d" followed by a "symfony server -d", and everything goes well on other courses, but this one is getting stuck.
**SOLUTION*
- *Rename compose.yaml ===> docker-compose.yaml
- Enabled some extenions in php.ini and it's works
Best,
Amine
Hey @Amine!
This might also be fixed by upgrading your symfony
binary. The Docker world is moving from docker-compose.yaml
to compose.yaml
(hence the change in your Symfony apps), but the symfony
binary needed to be updated for this change... which I know happened... and I think it was only in a couple of months ago.
Anyway, I hope that helps - that's my guess why your Docker variables suddenly vanished!
Cheers!
Hello,
When I try symfony console doctrine:database:create --if-not-exists
I have this error:
In ExceptionConverter.php line 87:
An exception occurred in the driver: could not find driver
I opened php.ini remove the comment to install msql extension, tried to comment
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=15&charset=utf8"
DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
but nothing changes...
I fixed the bug by uncomment extension=pdo_mysql
and extension=pdo_pgsql
in php.ini
.
Hey Alison,
I'm happy to hear you were able to fix this issue yourself! Yes, you need that PHP extension because we're using Doctrine in this project which stores data in the MySQL DB.
Btw, you only need to leave one DATABASE_URL uncommented in your .env file. If you leave both - the 2nd will always overwrite the 1st one, and it just mislead :)
Cheers!
Hi there,
I have an issue to boot the database container with Docker, I followed the Readme.md file but I encounter an error when running symfony console doctrine:database:create
. I receive the following error message:
Could not create database "app" for connection named default
An exception occurred in the driver: SQLSTATE[08006] [7] could not translate host name "database" to address: nodename nor servname provided, or not known``
here's my .env file content:
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=8650ba188bbf625cfea2df9a79ae6d61
###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ###
DATABASE_URL="postgresql://app:!ChangeMe!@database:5432/app?serverVersion=15&charset=utf8"
###< doctrine/doctrine-bundle ###
I'm using macOS Big Sur and Docker Desktop 24.0.6
The command composer compose -d
already created the database for me, if you skip symfony console doctrine:database:create --if-not-exists
and execute symfony console doctrine:schema:create
and symfony console doctrine:fixtures:load
you should be able to run symfony serve without any problem.
Hey Alison,
Thanks for this hint! One note: I suppose you meant docker compose -d
instead of composer compose -d
in the beginning? :)
Also, instead of symfony console doctrine:schema:create
it might be better to run symfony console doctrine:schema:update --force
that will apply the difference only if schema is already partially exits but not compete.
Cheers!
Hey @Padawan
That's a bit odd. I believe there's something wrong in your database service config in your docker-compose.yml
file. I'd start by double-checking that it is well configured
Cheers!
Hi @MolloKhan,
The problem was not related to my config files but to Docker-Desktop itself. Here is the solution
Thanks for posting that! I've highlighted your comment in case it helps others. I wish we knew why a small number of users have such a problem with the Docker setup. After all... that's kind of the point of Docker: to "just work" :p.
Sorry for the unrelated comment, but where can I find this great PHPStorm theme?
Hey PapyDanone,
It's Dark theme (Darkula in legacy PhpStorm) - you can change it in the PhpStorm preferences, search for "theme" there. But also a few extra plugins like "Atom Material Design" and "Rainbow Brackets".
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "4.x-dev", // 4.x-dev
"doctrine/doctrine-bundle": "^2.10", // 2.12.x-dev
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.4.x-dev
"doctrine/orm": "^2.16", // 2.18.x-dev
"knplabs/knp-time-bundle": "dev-main", // dev-main
"pagerfanta/doctrine-orm-adapter": "4.x-dev", // 4.x-dev
"pagerfanta/twig": "4.x-dev", // 4.x-dev
"symfony/asset": "6.4.*", // 6.4.x-dev
"symfony/asset-mapper": "6.4.*", // 6.4.x-dev
"symfony/console": "6.4.x-dev", // 6.4.x-dev
"symfony/dotenv": "6.4.x-dev", // 6.4.x-dev
"symfony/flex": "^2", // 2.x-dev
"symfony/form": "6.4.x-dev", // 6.4.x-dev
"symfony/framework-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/monolog-bundle": "^3.0", // dev-master
"symfony/runtime": "6.4.x-dev", // 6.4.x-dev
"symfony/security-csrf": "6.4.x-dev", // 6.4.x-dev
"symfony/stimulus-bundle": "2.x-dev", // 2.x-dev
"symfony/twig-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/ux-autocomplete": "2.x-dev", // 2.x-dev
"symfony/ux-live-component": "2.x-dev", // 2.x-dev
"symfony/ux-turbo": "2.x-dev", // 2.x-dev
"symfony/ux-twig-component": "2.x-dev", // 2.x-dev
"symfony/validator": "6.4.x-dev", // 6.4.x-dev
"symfony/web-link": "6.4.*", // 6.4.x-dev
"symfony/yaml": "6.4.x-dev", // 6.4.x-dev
"symfonycasts/dynamic-forms": "dev-main", // dev-main
"symfonycasts/tailwind-bundle": "dev-main", // dev-main
"tales-from-a-dev/flowbite-bundle": "dev-main", // dev-main
"twig/extra-bundle": "^2.12|^3.0", // 3.x-dev
"twig/twig": "^2.12|^3.0" // 3.x-dev
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.6.x-dev
"phpunit/phpunit": "^9.5", // 9.6.x-dev
"symfony/browser-kit": "6.4.*", // 6.4.x-dev
"symfony/css-selector": "6.4.*", // 6.4.x-dev
"symfony/debug-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/maker-bundle": "^1.51", // dev-main
"symfony/panther": "^2.1", // v2.1.1
"symfony/phpunit-bridge": "7.1.x-dev", // 7.1.x-dev
"symfony/stopwatch": "6.4.x-dev", // 6.4.x-dev
"symfony/web-profiler-bundle": "6.4.x-dev", // 6.4.x-dev
"zenstruck/browser": "1.x-dev", // 1.x-dev
"zenstruck/foundry": "^1.36" // 1.x-dev
}
}
Hey !
If you want to connect to your database with PHPStorm (or other things), update your
compose.override.yaml
file and replace :with :
I hope this helps !