gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
On our site, you can create your own vinyl mix. (Or you'll eventually be able to do this... right now, this button doesn't do anything). But another great feature of our site is the ability to browse other user's mixes.
Now that I'm looking at this, it might be useful if we could see when each mix was created.
If you don't remember where in our code this page was built, you can use a trick. Down on the web debug toolbar, hover over the 200 status code. Ah, ha! This shows us that the controller behind this page is VinylController::browse
.
Cool! Go open up src/Controller/VinylController.php
. Here is the browse
action:
... lines 1 - 9 | |
class VinylController extends AbstractController | |
{ | |
... lines 12 - 29 | |
'/browse/{slug}', name: 'app_browse') ( | |
public function browse(string $slug = null): Response | |
{ | |
$genre = $slug ? u(str_replace('-', ' ', $slug))->title(true) : null; | |
$mixes = $this->getMixes(); | |
return $this->render('vinyl/browse.html.twig', [ | |
'genre' => $genre, | |
'mixes' => $mixes, | |
]); | |
} | |
... lines 41 - 65 | |
} |
By the way, I did update the code a little bit since episode one... so make sure you've got a fresh copy if you're coding along with me.
This method calls $this->getMixes()
... which is a private function I created down at the bottom:
... lines 1 - 9 | |
class VinylController extends AbstractController | |
{ | |
... lines 12 - 41 | |
private function getMixes(): array | |
{ | |
// temporary fake "mixes" data | |
return [ | |
[ | |
'title' => 'PB & Jams', | |
'trackCount' => 14, | |
'genre' => 'Rock', | |
'createdAt' => new \DateTime('2021-10-02'), | |
], | |
[ | |
'title' => 'Put a Hex on your Ex', | |
'trackCount' => 8, | |
'genre' => 'Heavy Metal', | |
'createdAt' => new \DateTime('2022-04-28'), | |
], | |
[ | |
'title' => 'Spice Grills - Summer Tunes', | |
'trackCount' => 10, | |
'genre' => 'Pop', | |
'createdAt' => new \DateTime('2019-06-20'), | |
], | |
]; | |
} | |
} |
This returns a big array of fake data that represents the mixes we're going to render on the page. Eventually, we'll get this from a dynamic source, like a database.
Notice that each mix has a createdAt
date field. We get these mixes up in browse()
... and pass them as a mixes
variable into vinyl/browse.html.twig
. Let's jump into that template.
Down here, we use Twig's for
loop to loop over mixes
. Simple enough!
... lines 1 - 3 | |
<div class="container"> | |
... lines 5 - 25 | |
<div> | |
<h2 class="mt-5">Mixes</h2> | |
<div class="row"> | |
{% for mix in mixes %} | |
<div class="col col-md-4"> | |
<div class="mixed-vinyl-container p-3 text-center"> | |
<img src="https://via.placeholder.com/300" data-src="https://via.placeholder.com/300" alt="Square placeholder img"> | |
<p class="mt-2"><strong>{{ mix.title }}</strong></p> | |
<span>{{ mix.trackCount }} Tracks</span> | |
| | |
<span>{{ mix.genre }}</span> | |
</div> | |
</div> | |
{% endfor %} | |
</div> | |
</div> | |
</div> | |
... lines 43 - 44 |
Let's also now print the "created at" date. Add a |
, another <span>
and then say {{ mix.createdAt }}
.
There's just one problem. If you look at createdAt
... it's a DateTime
object. And you can't just print DateTime
objects... you'll get a big error reminding you... that you can't just print DateTime
objects. Cruel world!
Fortunately, Twig has a handy date
filter. We talked about filters briefly in the first episode: we using them by adding a |
after some value and then the name of the filter. This particular filter also takes an argument, which is the format the date should be printed. To keep things simple, let's use Y-m-d
, or "year-month-day".
... lines 1 - 3 | |
<div class="container"> | |
... lines 5 - 25 | |
<div> | |
<h2 class="mt-5">Mixes</h2> | |
<div class="row"> | |
{% for mix in mixes %} | |
<div class="col col-md-4"> | |
<div class="mixed-vinyl-container p-3 text-center"> | |
... lines 32 - 35 | |
<span>{{ mix.genre }}</span> | |
| | |
<span>{{ mix.createdAt|date('Y-m-d') }}</span> | |
</div> | |
</div> | |
{% endfor %} | |
</div> | |
</div> | |
</div> | |
... lines 45 - 46 |
Head over and refresh and... okay! We can now see when each was created, though the format isn't very attractive. We could do more work to spruce this up... but it would be way cooler if we could print this out in the "ago" format.
You've probably seen it before.... like for comments on a blog post... they say something like "posted three months ago" or "posted 10 minutes ago".
So... the question is: How can we convert a DateTime
object into that nice "ago" format? Well, that sounds like work to me and, as I said earlier, work in Symfony is done by a service. So the real question is: Is there a service in Symfony that can convert DateTime
objects to the "ago" format? The answer is... no. But there is a third party bundle that can give us that service.
Go to https://github.com/KnpLabs/KnpTimeBundle. If you look at this bundle's documentation, you'll see that it gives us a service that can do that conversion. So... let's get it installed!
Scroll to the composer require
line, copy that, spin over to our terminal, and paste.
composer require knplabs/knp-time-bundle
Cool! This grabbed knplabs/knp-time-bundle
... as well as symfony/translation
: Symfony's translation component, which is a dependency of KnpTimeBundle
. Near the bottom, it also configured two recipes. Let's see what those did. Run:
git status
Awesome! Any time you install a third party package, Composer will always modify your composer.json
and composer.lock
files. This also updated the config/bundles.php
file:
return [ | |
... lines 4 - 11 | |
Knp\Bundle\TimeBundle\KnpTimeBundle::class => ['all' => true], | |
]; |
That's because we just installed a bundle - KnpTimeBundle
- and its recipe handled that automatically. It also looks like the translation recipe added a config file and a translations/
directory. The translator is needed to use KnpTimeBundle... but we won't need to work with it directly.
So... what did installing this new bundle give us? Services of course! Let's find and use those next!
Hey @Gitanjali-N
Can you tell me if you get any console errors in your browser? Did you run yarn watch
? I'm guessing this problem could be related to your browser, if you try with a different one, does it work?
Also, try hard-refreshing the page
Hi @MolloKhan , thank you so much for your response. Indeed, it worked in another browser-profile window!
Git Versioning
I'm keeping a git version of this course as I code along. One challenge with downloading a fresh copy of the code is that it creates conflicts in my version control. Do you have any thoughts on to address this? If the changes are code specific, I don't think it's too big of a deal as I can just update the specific code changes where they exist. Are there any package changes between the first tutorial and this one-or even subsequent ones?
Thanks
Hey robertocannella,
I'm not sure I understand your problem completely. Do you mean, you have a course code from a different (past) tutorial, and wanted to follow the current course base on the finish code of the previous tutorial? If so, that's not something we recommend. We always recommend users to download a fresh course code for each tutorial to code along with us - this way you will have the exact code as the course author has. The reason behind of this is that we always d some upgrades and minor changes between our courses, so "finish course 1 code" != "start course 2 code", always.
But if you want, of course, you can try to follow the current course base on finish course code from the past tutorial, but be aware of possible changes and conflicts that we may done between courses that you would need to resolve manually. It's up to you :)
Cheers!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"knplabs/knp-time-bundle": "^1.18", // v1.19.0
"symfony/asset": "6.1.*", // v6.1.0-RC1
"symfony/console": "6.1.*", // v6.1.0-RC1
"symfony/dotenv": "6.1.*", // v6.1.0-RC1
"symfony/flex": "^2", // v2.1.8
"symfony/framework-bundle": "6.1.*", // v6.1.0-RC1
"symfony/http-client": "6.1.*", // v6.1.0-RC1
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/runtime": "6.1.*", // v6.1.0-RC1
"symfony/twig-bundle": "6.1.*", // v6.1.0-RC1
"symfony/ux-turbo": "^2.0", // v2.1.1
"symfony/webpack-encore-bundle": "^1.13", // v1.14.1
"symfony/yaml": "6.1.*", // v6.1.0-RC1
"twig/extra-bundle": "^2.12|^3.0", // v3.4.0
"twig/twig": "^2.12|^3.0" // v3.4.0
},
"require-dev": {
"symfony/debug-bundle": "6.1.*", // v6.1.0-RC1
"symfony/maker-bundle": "^1.41", // v1.42.0
"symfony/stopwatch": "6.1.*", // v6.1.0-RC1
"symfony/web-profiler-bundle": "6.1.*" // v6.1.0-RC1
}
}
Hi there,
I completed the previous course and it went well! On downloading a fresh copy of the code for this course and setting it up as per the readme file, the website is up and everthing works, except that the audios do not play and the turbo function is also not working. Any hints as to why this could be ?
Thanks!